views:

520

answers:

4

I'm sure I'm not the first person to need to do this, so I'm looking for the best way.

I've got a set of radio buttons with choices such as

  • This Year
  • Last Year
  • This Month
  • Last Month
  • This Week
  • Last Week

and I need to produce the proper relative date range from the current date (DateTime.Now).

For example if Last Year was selected and the current date was 4/2/09 14:45:32 I would need to return a start date of 1/1/08 00:00:00 and end date of 12/31/08 23:59:59.

Any thoughts?

A: 

I would create a factory method which will return an interface (or a delegate which you can execute) which would be passed the current date and return the date range for you based on the implementation.

Of course, which implementation you return from the factory method would be determined by the value of an enumeration you pass to it which corresponds to "this year", "last year", etc, etc.

casperOne
+5  A: 

This year:

DateTime Today = DateTime.Today;
DateTime StartDate = new DateTime(Today.Year,1,1);
DateTime EndDate = StartDate.AddYears(1).AddSeconds(-1);

This month:

DateTime Today = DateTime.Today;
DateTime StartDate = new DateTime(Today.Year,Today.Month,1);
DateTime EndDate = StartDate.AddMonths(1).AddSeconds(-1);

This week:

DateTime Today = DateTime.Today;
DateTime StartDate = Today.AddDays(-((int) Today.DayOfWeek));
DateTime EndDate = StartDate.AddDays(7).AddSeconds(-1);

Last year / month / week are simple variations on above. Edit: This week assumes the week starts on Sunday. You would have to modify the code slightly if your weeks start on Monday.

Keltex
I had the same code for ThisWeek, and realized that adding 7 days will get you midnight on Saturday/Sunday. If you're just using the dates, and not the times, that's technically 8 days, so I edited mine to only add 6 days.
Chris Doggett
@Chris: depends on your definition of "this week". I usually think of weeks starting on Sunday, but some people think of it on Monday. Easy to modify the code as appropriate.
Keltex
I re-read the question, and you're correct. I wrongly assumed he just wanted the dates, when it should go to 11:59:59PM
Chris Doggett
+2  A: 

All of these have been tested using DateTime.Today, and work just like you asked for:

public struct DateRange
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

public static DateRange ThisYear(DateTime date)
{
    DateRange range = new DateRange();

    range.Start = new DateTime(date.Year, 1, 1);
    range.End = range.Start.AddYears(1).AddSeconds(-1);

    return range;
}

public static DateRange LastYear(DateTime date)
{
    DateRange range = new DateRange();

    range.Start = new DateTime(date.Year - 1, 1, 1);
    range.End = range.Start.AddYears(1).AddSeconds(-1);

    return range;
}

public static DateRange ThisMonth(DateTime date)
{
    DateRange range = new DateRange();

    range.Start = new DateTime(date.Year, date.Month, 1);
    range.End = range.Start.AddMonths(1).AddSeconds(-1);

    return range;
}

public static DateRange LastMonth(DateTime date)
{
    DateRange range = new DateRange();

    range.Start = (new DateTime(date.Year, date.Month, 1)).AddMonths(-1);
    range.End = range.Start.AddMonths(1).AddSeconds(-1);

    return range;
}

public static DateRange ThisWeek(DateTime date)
{
    DateRange range = new DateRange();

    range.Start = date.Date.AddDays(-(int)date.DayOfWeek);
    range.End = range.Start.AddDays(7).AddSeconds(-1);

    return range;
}

public static DateRange LastWeek(DateTime date)
{
    DateRange range = ThisWeek(date);

    range.Start = range.Start.AddDays(-7);
    range.End = range.End.AddDays(-7);

    return range;
}
Chris Doggett
I ended up using this code, as it was the most complete and the easiest to modify to fit my needs. Kaltex's was perfectly acceptable as well.
Lawrence Johnston
A: 

I would use the DateTime built-in methods for Adding and returning specific portions of the date to write a function that would return the interval.

eppdog