mde / timezone-js

DEPRECATED: Timezone-enabled JavaScript Date object. Uses Olson zoneinfo files for timezone data.
824 stars 183 forks source link

NZ daylight savings causes incorrect date #146

Closed ryanwilliams closed 4 years ago

ryanwilliams commented 10 years ago

From what I understand these should both be the same time, but they're not. This is the day New Zealand moved from NZDT to NZST.

var timestamp = 1396742400308
(new timezoneJS.Date(timestamp, 'Etc/UTC')).toUTCString()
// > "Sun, 06 Apr 2014 00:00:00 GMT"

(new timezoneJS.Date(timestamp, 'Pacific/Auckland')).toUTCString()
// > "Sun, 06 Apr 2014 02:00:00 GMT"
ryanwilliams commented 10 years ago

Similar issue happens with a ISO time string, but the error different. My machine timezone is set to Auckland. Browser is Chrome, OS is OSX 10.9.2.

(new timezoneJS.Date("2014-04-06T00:00:00Z", 'Etc/UTC')).toISOString()
// > "2014-04-06T02:00:00.000Z"

(new timezoneJS.Date("2014-04-05T13:00:00Z", 'Etc/UTC')).toISOString()
// > "2014-04-05T13:00:00.000Z"

// Winter time kicks in here

(new timezoneJS.Date("2014-04-05T14:00:00Z", 'Etc/UTC')).toISOString()
// > "2014-04-05T17:00:00.000Z"
(new Date("2014-04-05T14:00:00Z")).toISOString()
// > "2014-04-05T14:00:00.000Z"
ryanwilliams commented 10 years ago

The flaw seems to be in this line:

this._timeProxy = Date.UTC(this.year, this.month, this.date, this.hours, this.minutes, this.seconds, this.milliseconds);

If the dateProxy has been adjusted to a time that's outside of the current daylight savings period then Date.UTC will not account for that change and the result is an incorrect timestamp.

This is most obvious here where the clone doesn't have the same time as the original. (Machine is in Auckland time, daylight savings ended on Sun 6th Apr 2am Auckland time).

var foo = new timezoneJS.Date("2014-04-05T14:00:00Z", 'Etc/UTC')
foo.getTime() == foo.clone().getTime()
// > false