111

Possible Duplicate:
How to get the last day of a month?

So far, I have this:

DateTime createDate = new DateTime(year, month, 1).AddMonths(1).AddDays(-1);

Is there a better way?

Community
  • 1
  • 1
Irwin
  • 12,551
  • 11
  • 67
  • 97
  • 7
    Have you ever written your own calendar before? This is a fantastic solution by comparison. :D – Neil Nov 02 '10 at 15:06
  • 1
    Just looking back at this post, how could this be a duplicate? My question poses a way, and then queries if there's something better. The one referenced is just asking for any method. – Irwin Mar 27 '13 at 12:53
  • I hate when people mark question a duplicate without referencing to the other question. If you think there is a better question and answer I would like to see that too. – dvdmn Aug 15 '18 at 14:07

4 Answers4

274

How about using DaysInMonth:

DateTime createDate = new DateTime (year, month,
                                    DateTime.DaysInMonth(year, month));

(Note to self - must make this easy in Noda Time...)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    @JonSkeet Did you ever make this easy in NodaTime, or is this still the best way to do this? – Ben Jenkinson Jan 30 '15 at 16:51
  • 1
    @BenJenkinson: It's definitely still the best way at the moment. In 2.0 you could use a `DateAdjuster` - there isn't one for `LastDayOfMonth` at the moment, but I might add one tonight :) – Jon Skeet Jan 30 '15 at 18:11
  • 4
    @BenJenkinson: Ha - it turns out I *had* already done it - `DateAdjusters.EndOfMonth`. – Jon Skeet Jan 30 '15 at 22:06
  • @JonSkeet That's great thank you, I've taken that method's internals to use as my own extension method until NodaTime 2.0 comes out. In my case, I also want to find the "last possible instant of a specified date", does this method sound reasonable? `anyLocalDate.PlusDays(1).AtMidnight().PlusTicks(-1)` – Ben Jenkinson Feb 02 '15 at 10:06
  • @JonSkeet: Sorry, I should probably make that a separate question. – Ben Jenkinson Feb 02 '15 at 10:12
  • @BenJenkinson: It would probably make a useful question, yes. (And suggests a feature request :) – Jon Skeet Feb 02 '15 at 10:14
  • @JonSkeet: I've added it here: http://stackoverflow.com/q/28275393/590382 – Ben Jenkinson Feb 02 '15 at 10:18
  • Why is this better than the AddDays(-1) in the original question? – stevec Oct 07 '15 at 12:05
  • @stevec: Personally I think it's clearer - it reflects how someone would approach it as a human, I believe. ("I want a date for the last day in September... okay, how many days are there in September?") – Jon Skeet Oct 07 '15 at 12:56
  • Funny. This human's approach was 'first day of month is always 1st, last day of previous month is the day before that'. I was solving the problem of 'find the previous month end date for a given date' which might explain it . . . – stevec Oct 09 '15 at 16:30
  • Try this if you want to calculate it depending of today date: `DateTime LastDateOfThisMonth = new DateTime (DateTime.Today.Year, DateTime.Today.Month, DateTime.DaysInMonth(DateTime.Today.Year, DateTime.Today.Month)); ` – César Oct 24 '19 at 09:12
  • 1
    @César: It's a really bad idea to call `DateTime.Today` multiple times like this. It could give different results half way through, if you call it around midnight. Far better to write a method that accepts a single `DateTime` and uses that consistently. – Jon Skeet Oct 24 '19 at 09:42
  • @JonSkeet Oh..that's true!! Sorry for it! You are right – César Oct 25 '19 at 10:04
27

You can use the method DateTime.DaysInMonth(year,month) to get the number of days in any given month.

Øyvind Bråthen
  • 59,338
  • 27
  • 124
  • 151
8

Here's an elegant approach I found in a useful DateTime extension library on CodePlex:

http://datetimeextensions.codeplex.com/

Here's some sample code:

    public static DateTime First(this DateTime current)
    {
        DateTime first = current.AddDays(1 - current.Day);
        return first;
    }

    public static DateTime First(this DateTime current, DayOfWeek dayOfWeek)
    {
        DateTime first = current.First();

        if (first.DayOfWeek != dayOfWeek)
        {
            first = first.Next(dayOfWeek);
        }

        return first;
    }

    public static DateTime Last(this DateTime current)
    {
        int daysInMonth = DateTime.DaysInMonth(current.Year, current.Month);

        DateTime last = current.First().AddDays(daysInMonth - 1);
        return last;
    }

It has a few other useful extensions as well that may be helpful to you.

Donald
  • 1,718
  • 10
  • 18
  • 1
    I know this is an old post - happened across it today, and codeplex is a bit dead, but I wanted to point out your 2nd First() uses another extension that you didn't provide in your code which is the Next function: public static DateTime Next(this DateTime current, DayOfWeek dayOfWeek) { int offsetDays = dayOfWeek - current.DayOfWeek; if (offsetDays <= 0) { offsetDays += 7; } DateTime result = current.AddDays(offsetDays); return result; } – B.O.B. Oct 13 '19 at 03:37
2

if you're interested in a custom code version:

var anyDt = DateTime.Now;
var lastDayOfMonth = anyDt.AddMonths(1).AddDays(anyDt.AddMonths(1).Day).Date;

or:

var anyDt = DateTime.Now;
var lastDayOfMonth = anyDt.AddDays(1-anyDt.Day).AddMonths(1).AddDays(-1).Date; 

or as a method:

DateTime LastDayInMonth(DateTime anyDt)
   { return anyDt.AddMonths(1).AddDays(anyDt.AddMonths(1).Day).Date; }

or as an extension method:

DateTime LastDayInMonth(DateTime this anyDt)
   { return anyDt.AddMonths(1).AddDays(anyDt.AddMonths(1).Day).Date; }
Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • At best, this code returns the first day of the next month, not the last day of current month. Also, it runs into issues when handling months with differing number of days. If today were 1/4/2017, this code will return 2/1/2017. If today were 1/31/ 2017, this code will return 1/29/2017. – pistol-pete Jan 04 '17 at 16:01