Nanda K
Nanda K

Reputation: 11

new Date() not working as expected when exact daylight switch happens

I have a scenario where I have to pass "year,month,date,time" to Date() function and get the datetime type.

  1. Using chrome.
  2. Windows has been configured with EST timezone(-05:00).
  3. DST starts On March 8th 2020 2AM(EDT -04:00)

If i pass date time as Date(2020,02,08,01) it returns as "Sun Mar 08 2020 01:00:00 GMT-0500 (Eastern Standard Time)".

But when I pass date time for 2AM(exactly where dst switches) it returns as "Sun Mar 08 2020 03:00:00 GMT-0400 (Eastern Daylight Time)".

It returning Time as "03" istead of "02".

Can anyone let me know why the Date function not working as I expect for the particular time and how to fix this issue?

Upvotes: 0

Views: 573

Answers (2)

Christoph
Christoph

Reputation: 2327

The result is correct.

Date(2020,02,08,01,59,00) returns Sun Mar 08 2020 01:59:00 GMT-0500
Date(2020,02,08,02,00,00) returns Sun Mar 08 2020 03:00:00 GMT-0400

In Spring, clocks skip forward by an hour. Notice how the offset to GMT is decreased by one hour? That's daylight savings time on the East Coast.

There IS no 2AM (GMT-05) on March 8, at least not in the Eastern timezone. One second after 01:59:59 GMT-05:00 the clock jumps to 03:00:00 GMT -04:00. The jump is reflected in the GMT, which really is an offset to GMT.

What is going under the hood is the following: When you create a new Date, Javascript parses it and internally stores the exact time in ticks after 1/1/1970 GMT00:00 (the epoch, in Greenwich mean time). When you now try to get information like year, month, day, hour from this internal value, Javascript applies your local timezone to determine what local time it should return. So when you create your date object from Date(2020,02,08,02,00,00), JS assumes that this is still Standard (winter) time because there is no 2am in Daylight Savings time. The value in ticks is the same as 03:00:00 GMT-00:40, and when you then print or otherwise access the hour value of this date, Javascript localizes it to your timezone. But again, the two times 02:00:00 GMT-05:00 and 03:00:00 GMT-04:00 are identical, only expressed in different timezones/daylight savings periods.

Please note that your date/time parsing logic will run into problems in Fall as the hour between 1 and 2 is "executed" twice. Per TimeAndDate, on 11/1 at 2am the clock will be set back to 1am. So

Date(2020, 10, 01, 01, 30, 00)

cannot determine whether it is still EDT or already EST. You need to pass in the current time zone/offset to UTC.

Upvotes: 0

mplungjan
mplungjan

Reputation: 178421

We have DST on the 29th of March - works as expected in GMT-1/GMT-2

console.log(new Date(2020,2,29,0,0,0,0)); // in CEST I get "2020-03-28T23:00:00.000Z"
console.log(new Date(2020,2,29,1,0,0,0))  // in CEST I get "2020-03-29T00:00:00.000Z"
console.log(new Date(2020,2,29,2,0,0,0))  // in CEST I get "2020-03-29T01:00:00.000Z"
console.log(new Date(2020,2,29,3,0,0,0))  // in CEDT I get "2020-03-29T01:00:00.000Z" !!!
console.log(new Date(2020,2,29,4,0,0,0))  // in CEDT I get "2020-03-29T02:00:00.000Z"

Perhaps you want UTC

console.log(new Date(Date.UTC(2020,2,29,0,0,0,0))); // in CET I get "2020-03-29T00:00:00.000Z"
console.log(new Date(Date.UTC(2020,2,29,1,0,0,0))); // in CET I get "2020-03-29T01:00:00.000Z"
console.log(new Date(Date.UTC(2020,2,29,2,0,0,0))); // in CET I get "2020-03-29T02:00:00.000Z"
console.log(new Date(Date.UTC(2020,2,29,3,0,0,0))); // in CET I get "2020-03-29T03:00:00.000Z" 
console.log(new Date(Date.UTC(2020,2,29,4,0,0,0))); // in CET I get "2020-03-29T04:00:00.000Z"

Or in your case - UTC on the 8th:

console.log(new Date(Date.UTC(2020,2,8,0,0,0,0))); // in CET I get "2020-03-08T00:00:00.000Z"
console.log(new Date(Date.UTC(2020,2,8,1,0,0,0))); // in CET I get "2020-03-08T01:00:00.000Z"
console.log(new Date(Date.UTC(2020,2,8,2,0,0,0))); // in CET I get "2020-03-08T02:00:00.000Z"
console.log(new Date(Date.UTC(2020,2,8,3,0,0,0))); // in CET I get "2020-03-08T03:00:00.000Z" 
console.log(new Date(Date.UTC(2020,2,8,4,0,0,0))); // in CET I get "2020-03-08T04:00:00.000Z"

Upvotes: 0

Related Questions