views:

8322

answers:

9

I can't think of an easy one or two liner that would get the previous months first day and last day.

I am LINQ-ifying a survey web app, and they squeezed a new requirement in.

The survey must include all of the service requests for the previous month. So if it is April 15th, I need all of Marches request ids.

var RequestIds = (from r in rdc.request 
                  where r.dteCreated >= LastMonthsFirstDate && 
                  r.dteCreated <= LastMonthsLastDate 
                  select r.intRequestId);

I just can't think of the dates easily without a switch. Unless I'm blind and overlooking an internal method of doing it.

+7  A: 

The way I've done this in the past is first get the first day of this month

dFirstDayOfThisMonth = DateTime.Today.AddDays( - ( DateTime.Today.Day - 1 ) );

Then subtract a day to get end of last month

dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1);

Then subtract a month to get first day of previous month

dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1);
MikeW
net 2.0, Today.Days isn't working.
Max Gontar
Thirty seconds in the Framework help file found DateTime.Day, which gets you the solution. MikeW's answer was enough to aim you in the right direction.
Ken White
Also, the example in the help file for DateTime.Day shows doing almost exactly what you need.
Ken White
DateTime.Today.Day you mean
Max Gontar
+1, but to be pedantic, you're better evaluating DateTime.Today once and storing in a local variable. If your code starts executing a nanosecond before midnight, two consecutive calls to DateTime.Today could return different values.
Joe
Yes, thanks, all of you correct, even the pedantic one Fixed the error.
MikeW
well let the compiler be less pedantic to you :)
Max Gontar
+2  A: 
DateTime LastMonthLastDate = DateTime.Today.AddDays(0 - DateTime.Today.Day);
DateTime LastMonthFirstDate = LastMonthLastDate.AddDays(1 - LastMonthLastDate.Day);
Franci Penov
DateTime.Today.Days -> 'System.DateTime' does not contain a definition for 'Days'...
Andrew Robinson
DateTime.Today.Day you mean
Max Gontar
+12  A: 
var first = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(-1);
var last = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddDays(-1);

In-line them if you want.

Andrew Robinson
IIRC DateTime.Today is a quite expensive call, so you better store the value in a variable first. Good answer anyway :)
Leandro López
I would likely implement this as a pair of extension methods given a need.DateTime.PreviouseMonth().FirstDay();DateTime.PreviouseMonth().LastDay();
Andrew Robinson
A: 
DateTime now = DateTime.Now;
int prevMonth = now.AddMonths(-1).Month;
int year = now.AddMonths(-1).Year;
int daysInPrevMonth = DateTime.DaysInMonth(year, prevMonth);
DateTime firstDayPrevMonth = new DateTime(year, prevMonth, 1);
DateTime lastDayPrevMonth = new DateTime(year, prevMonth, daysInPrevMonth);
Console.WriteLine("{0} {1}", firstDayPrevMonth.ToShortDateString(),
  lastDayPrevMonth.ToShortDateString());
Max Gontar
What if DateTime.Now yields 2009-01-31 on the first call and 2009-02-01 on the second call?
David B
That'll be the end of DateTime.Now :) editing. thanks.
Max Gontar
A: 

If there's any chance that your datetimes aren't strict calendar dates, you should consider using enddate exclusion comparisons... This will prevent you from missing any requests created during the date of Jan 31.

DateTime now = DateTime.Now;
DateTime thisMonth = new DateTime(now.Year, now.Month, 1);
DateTime lastMonth = thisMonth.AddMonths(-1);

var RequestIds = rdc.request
  .Where(r => lastMonth <= r.dteCreated)
  .Where(r => r.dteCreated < thisMonth)
  .Select(r => r.intRequestId);
David B
A: 

An approach using extension methods:

class Program { static void Main(string[] args) { DateTime t = DateTime.Now;

    DateTime p = t.PreviousMonthFirstDay();
    Console.WriteLine( p.ToShortDateString() );

    p = t.PreviousMonthLastDay();
    Console.WriteLine( p.ToShortDateString() );


    Console.ReadKey();
}

}

public static class Helpers
{
    public static DateTime PreviousMonthFirstDay( this DateTime currentDate )
    {
        DateTime d = currentDate.PreviousMonthLastDay();

        return new DateTime( d.Year, d.Month, 1 );
    }

    public static DateTime PreviousMonthLastDay( this DateTime currentDate )
    {
        return new DateTime( currentDate.Year, currentDate.Month, 1 ).AddDays( -1 );
    }
}

See this link http://www.codeplex.com/fluentdatetime for some inspired DateTime extensions.

rp
A: 

EDIT: This is not the way to do it!
If today.Month - 1 = 0, as in Jan, this will throw an exception. This is clearly a case where being clever gets you in trouble!

A little simpler than the accepted answer:

var today = DateTime.Today
var first = new DateTime(today.Year, today.Month - 1, 1);
var last  = new DateTime(today.Year, today.Month, 1).AddDays(-1);

Saves an extra DateTime creation.

Gavin Miller
A: 

using Fluent DateTime http://fluentdatetime.codeplex.com/

        var lastMonth = 1.Months().Ago().Date;
        var firstDayOfMonth = lastMonth.FirstDayOfMonth();
        var lastDayOfMonth = lastMonth.LastDayOfMonth();
Simon
A: 

thnxzzzzzzzzz Andrew Robinson

shahzad hussain