I stumbled into a confusing behavior in JS, and figured out that it’s a basic, logical behavior, but it baffled me a while.
When I added a month to a date, the timezone offset would sometimes change. Most of the time, it would not, but sometimes, it would.
I ran this code on February 13, 2019.
function addMonth( d, increment ) {
var m = d.getMonth();
var next = m + increment;
var nextYear = d.getFullYear() + Math.floor( next / 12 );
var nextMonth = Math.abs( next % 12 );
var newDate = new Date( nextYear, nextMonth, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds() );
return newDate;
}
x = new Date();
y = addMonth( x, 1 );
console.log(x);
console.log(y);
console.log(x.getTimezoneOffset());
console.log(y.getTimezoneOffset());
The results were in the consoles:
Firefox:
Date 2019-02-13T22:13:58.837Z
Date 2019-03-13T21:13:58.837Z
480
420
Chrome:
Wed Feb 13 2019 14:07:48 GMT-0800 (Pacific Standard Time)
Wed Mar 13 2019 14:07:48 GMT-0700 (Pacific Daylight Time)
480
420
Edge:
Wed Feb 13 2019 14:16:21 GMT-0800 (Pacific Standard Time)
Wed Mar 13 2019 14:16:21 GMT-0700 (Pacific Daylight Time)
480
420
The Firefox results had me totally baffled: it looked like an hour vanished, because I didn’t see that the timezone had changed, until I used getTimezoneOffset() to get the zone.
The other two debuggers were more informative.
So, what happened?
I created x today, when we’re using Standard Time.
In the function, it increments the month to create a new Date, and returns it. That’s all. It doesn’t mess with timezones.
y falls on March 13, which is within Daylight Savings Time in the Pacific zone. DST in the US starts on March 10, 2019.
So, when it creates a new Date, using a list of parameters, they are assumed to be local time values. These are converted to UTC, and stored.
When it displays the date, it uses the stored UTC date (which never has DST), and gets the local system’s timezone. If the month and date fall within DST for that timezone, it uses the DST version of the timezone. Otherwise, it uses the standard local timezone.
The Fix
I could use the UTC versions of the functions to avoid this problem: UTC does not have DST.
References
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
https://stackoverflow.com/questions/4018320/javascript-date-objects-and-daylight-savings-time