The Date methods "fix" weird non-real dates. If you set the date (day-of-month) to zero, you get the last day of the previous month. All of the setter methods behave similarly.
Note also that months are numbered from zero: January is 0, not 1.
Answer from Pointy on Stack OverflowVideos
The Date methods "fix" weird non-real dates. If you set the date (day-of-month) to zero, you get the last day of the previous month. All of the setter methods behave similarly.
Note also that months are numbered from zero: January is 0, not 1.
For the first case, you're getting 30 because you're checking the number of days in the 4th month - April. May is the 5th month. Here's a demo - with February as the 2nd month as well:
console.log(new Date(2019, 04, 00).getDate());
console.log(new Date(2019, 05, 00).getDate());
console.log(new Date(2019, 02, 00).getDate());
The second case does actually produce 1:
console.log(new Date('2019-04-01').getDate());
And the third case does actually produce 2:
console.log(new Date('2019-04-02').getDate());
Redditors, Can someone please explain why (what is the reasoning/advantage)
below have direct methods
Date.UTC() Date.now() Date.parse()
And below have prototype methods
Date.prototype.getDate() Date.prototype.getDay()
For testing:
const functionName = fn => (console.log(fn.name), fn); functionName(Date.prototype.getDate); // logs getDate functionName(Date.getDate); // logs Cannot read property 'name' of undefined functionName(Date.now); // logs now
See the documentation
Specifically - "If a time zone is not specified and the string is in an ISO format recognized by ES5, UTC is assumed. GMT and UTC are considered equivalent. The local time zone is used to interpret arguments in RFC2822 Section 3.3 format (or any format not recognized as ISO 8601 in ES5) that do not contain time zone information"
and
"Given a date string of "March 7, 2014", parse() assumes a local time zone, but given an ISO format such as "2014-03-07" it will assume a time zone of UTC. Therefore Date objects produced using those strings will represent different moments in time unless the system is set with a local time zone of UTC"
The last 2 of your examples are "ISO format recognized by ES5"
Date("January 1, 2015") is interpreted as local date.
Date("2015-01-01") is interpreted as a UTC date in ES5, local date in ES6.
getDate() gets the local date.
getUTCdate() gets the UTC date.
When you mix and match local and UTC, then you get surprising results.
Thanks, @preston-s. Your comments took me a long way towards answering my question. But, it's interesting that the interpretation of Date("2015-01-01") will change from UTC in ES5 to local time in ES6. Does anyone know when the different browsers are expected to switch over to the new behavior? I would expect some things to break at that point in time.
ES5: 'The value of an absent time zone offset is “Z”.'
ES6: 'If the time zone offset is absent, the date-time is interpreted as a local time.'
Given all this information, here are two solutions which will work across ES5 and ES6. Several other solutions are possible.
1) Use local date in and out.
var d;
d = new Date("January 1, 2015");
alert('Month: ' + d.getMonth() + ' Date: ' + d.getDate() + ' UTC: ' + d.toUTCString());
// Month: 0 Date: 1 UTC: Thu, 01 Jan 2015 05:00:00 GMT
2) Use UTC date in and out. Spell out the time zone so this will still work in ES6.
var d;
d = new Date("2015-01-01T00:00:00.000Z");
alert('UTC Month: ' + d.getUTCMonth() + ' UTC Date: ' + d.getUTCDate() + ' UTC: ' + d.toUTCString());
// UTC Month: 0 UTC Date: 1 UTC: Thu, 01 Jan 2015 00:00:00 GMT