Reputation: 1727
Why does this happen -
var date = new Date('2015-10-24T23:31:04.181Z');
date.toISOString(); // "2015-10-24T23:31:04.181Z"
date.setMilliseconds(date.getMilliseconds() + 1);
date.toISOString(); // "2015-10-24T22:31:04.182Z"
Is it a time zone issue ? Why doesn't it happen with all date values ?
Thanks
Upvotes: 2
Views: 1062
Reputation: 1074276
It's daylight savings time, in a really non-obvious way. :-)
2015-10-24T23:31:04.181Z in Jerusalem is Oct 25 2015 01:31:04 GMT+0200 (Jerusalem Standard Time) on the date/time when DST ends and the clocks go back (reference). Specifically, it's within the Groundhog Hour: There are two 01:31:04s that day, first the one in summer time, then the one an hour later in standard time.
You're using setMilliseconds
, which is a local time function. As you probably know, JavaScript's Date
is smart about handling rollover between date fields (although there is no rollover in this particular case), and so the logic of setMilliseconds
has to handle allowing for possible rollover. This is detailed in the specification, but fundamentally it takes the current time value (milliseconds since The Epoch), makes a local date/time out of it, does the work, and then has to turn that local date/time back into a new time value.
But here's where the problem kicks in: Those two 01:31:04s that day. V8 has to choose one when determining the real date/time. It chooses the one in summer time, which is an hour earlier than your original date/time.
If you use setUTCMilliseconds
, this doesn't happen, because there's no round-trip to local time.
Moral of the story: If you're working in UTC, work exclusively in UTC. :-)
Upvotes: 4