If you provide 0
as the dayValue
in Date.setFullYear
you get the last day of the previous month:
d = new Date(); d.setFullYear(2008, 11, 0); // Sun Nov 30 2008
There is reference to this behaviour at mozilla. Is this a reliable cross-browser feature or should I look at alternative methods?
I recently had to do something similar, this is what I came up with:
Pass it in a date, and it will return a date set to either the beginning of the month, or the end of the month.
The
begninngOfMonth
function is fairly self-explanatory, but what's going in in theendOfMonth
function is that I'm incrementing the month to the next month, and then usingsetDate(0)
to roll back the day to the last day of the previous month which is a part of the setDate spec:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate https://www.w3schools.com/jsref/jsref_setdate.asp
I then set the hour/minutes/seconds to the end of the day, so that if you're using some kind of API that is expecting a date range you'll be able to capture the entirety of that last day. That part might go beyond what the original post is asking for but it could help someone else looking for a similar solution.
Edit: You can also go the extra mile and set milliseconds with
setMilliseconds()
if you want to be extra precise.In computer terms,
new Date()
andregular expression
solutions are slow! If you want a super-fast (and super-cryptic) one-liner, try this one (assumingm
is inJan=1
format). I keep trying different code changes to get the best performance.My current fastest version:
After looking at this related question Leap year check using bitwise operators (amazing speed) and discovering what the 25 & 15 magic number represented, I have come up with this optimized hybrid of answers:
Given the bit-shifting this obviously assumes that your
m
&y
parameters are both integers, as passing numbers as strings would result in weird 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.The only real competition for speed is from @GitaarLab, so I have created a head-to-head JSPerf for us to test on: http://jsperf.com/days-in-month-head-to-head/5
It works based on my leap year answer here: javascript to find leap year this answer here Leap year check using bitwise operators (amazing speed) as well as the following binary logic.
A quick lesson in binary months:
If you interpret the index of the desired months (Jan = 1) in binary you will notice that months with 31 days either have bit 3 clear and bit 0 set, or bit 3 set and bit 0 clear.
That means you can shift the value 3 places with
>> 3
, XOR the bits with the original^ m
and see if the result is1
or0
in bit position 0 using& 1
. Note: It turns out+
is slightly faster than XOR (^
) and(m >> 3) + m
gives the same result in bit 0.JSPerf results: http://jsperf.com/days-in-month-perf-test/6
This one works nicely:
A slight modification to solution provided by lebreeze:
This will give you current month first and last day.
If you need to change 'year' remove d.getFullYear() and set your year.
If you need to change 'month' remove d.getMonth() and set your year.
My colleague stumbled upon the following which may be an easier solution
stolen from http://snippets.dzone.com/posts/show/2099