Coder Perfect

Calculate the month’s last day.

Problem

You obtain the last day of the previous month if you provide 0 as the dayValue in Date.setFullYear:

d = new Date(); d.setFullYear(2008, 11, 0); //  Sun Nov 30 2008

At Mozilla, there is a mention of this behavior. Is this a cross-browser functionality that I can trust, or should I look into other options?

Asked by Ken

Solution #1

IE 6:                     Thu Jan 31 00:00:00 CST 2008
IE 7:                     Thu Jan 31 00:00:00 CST 2008
IE 8: Beta 2:             Thu Jan 31 00:00:00 CST 2008
Opera 8.54:               Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.27:               Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.60:               Thu Jan 31 2008 00:00:00 GMT-0600
Firefox 2.0.0.17:         Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Firefox 3.0.3:            Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Google Chrome 0.2.149.30: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Safari for Windows 3.1.2: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)

The discrepancies in output are due to differences in the implementation of function toString() { [native code] }(), not because the dates are different.

Of fact, just because the browsers listed above utilize 0 as the preceding month’s last day does not indicate they will continue to do so, or that browsers not listed will do so as well, but it lends credence to the assumption that it should function the same way in all browsers.

Answered by Grant Wagner

Solution #2

This appears to be the best option for me. Allow the Date object to do the math for you.

var today = new Date();
var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth()+1, 0);

Your words will be rewritten by QuillBot. Start by typing or copying something into this box, then hit the enter key.

Answered by orad

Solution #3

I’d make an intermediate date with the first day of the following month and then return the previous day’s date:

int_d = new Date(2008, 11+1,1);
d = new Date(int_d - 1);

Answered by koni

Solution #4

New Date() and regular expression solutions are slow in computer terms! Try this one-liner (assuming m is in Jan=1 format) if you want a super-fast (and super-cryptic) one-liner. To get the optimum performance, I continuously experimenting with different code changes.

My current quickest version is as follows:

I came up with this optimized blend of responses after looking at this related question Leap year check using bitwise operators (incredible speed) and discovering what the 25 & 15 magic numbers represented:

function getDaysInMonth(m, y) {
    return m===2 ? y & 3 || !(y%25) && y & 15 ? 28 : 29 : 30 + (m+(m>>3)&1);
}

Given the bit-shifting, it’s safe to presume that your m and y parameters are both integers, as sending numbers as strings might provide strange results.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/H89X3/22/

JSPerf results: http://jsperf.com/days-in-month-head-to-head/5

For some reason, (m+(m>>3)&1) is more efficient than (5546>>m&1) on almost all browsers.

Because @GitaarLab is the only actual speed competitor, I’ve prepared a head-to-head JSPerf for us to test on: http://jsperf.com/days-in-month-head-to-head/5

It works like this, based on my leap year answer: This answer uses javascript to find the leap year. Leap year check with bitwise operators (incredible speed) and the binary logic below.

A basic primer on binary months is as follows:

Months with 31 days have bit 3 clear and bit 0 set, or bit 3 set and bit 0 clear, according to the binary interpretation of the desired months’ index (Jan = 1).

Jan = 1  = 0001 : 31 days
Feb = 2  = 0010
Mar = 3  = 0011 : 31 days
Apr = 4  = 0100
May = 5  = 0101 : 31 days
Jun = 6  = 0110
Jul = 7  = 0111 : 31 days
Aug = 8  = 1000 : 31 days
Sep = 9  = 1001
Oct = 10 = 1010 : 31 days
Nov = 11 = 1011
Dec = 12 = 1100 : 31 days

That implies you can use >> 3 to shift the value three places, XOR the bits with the original m, then use & 1 to see if the result is 1 or 0 in bit position 0. Note that + is slightly faster than XOR (), and (m >> 3) + m in bit 0 yields the same result.

JSPerf results: http://jsperf.com/days-in-month-perf-test/6

Answered by Gone Coding

Solution #5

My colleague came up the following, which could be a simpler approach.

function daysInMonth(iMonth, iYear)
{
    return 32 - new Date(iYear, iMonth, 32).getDate();
}

stolen from http://snippets.dzone.com/posts/show/2099

Answered by lebreeze

Post is based on https://stackoverflow.com/questions/222309/calculate-last-day-of-month