Error in Date value at beginning of DST in certain time zones

Symptoms

When you use the JavaScript Date object to compute dates under certain circumstances, users may see results that are apparently incorrect. This behavior occurs when the following conditions are true:
  • The time zone configured in Date and Time Settings transitions from standard time to Daylight Saving Time (DST) at midnight.
  • The date arithmetic uses Date objects that are constructed without hours and minutes (or that use 0 for the hours and minutes), and instead uses just the date of the transition from standard time to DST.

For example, trying to construct a Date of October 17th 2010 yields a date of October 16th:  


var dt = new Date(2010, 9,17);


// ...


console.log(dt.toString()); // evaluates to "Sat Oct 16 23:00:00 UTC-0300 2010"


dt.getDate() // evaluates to 16

Cause

This is a specific instance of a problem that occurs when a Date() object is initialized to exactly the time when DST begins.

The values that are used to construct the Date object represent a time after the point where standard time ends, but earlier than a local clock would show after DST has begun. The ECMAScript Language Specification specifies that a DaylightSavingTA adjustment of 1 hour be subtracted when calculating the “time value,” the internal representation of the Date object. However, this ends up representing a time before DST would begin. In the case of Brazil, this occurs at midnight, and therefore the Date object ends up representing a time from the previous day.

Resolution

This behavior conforms to the ECMAScript standard, and it is therefore by design.  

When you're concerned only with the day, month, and year, you can work around this behavior by constructing Date objects by using an Hours value that is not zero—that is, an Hours value that is safely larger than the daylight saving time adjustment.

More Information

The ECMAScript standard can be found at ECMAScript® 2016 Language Specification.

Section 15.9.3.1 defines how the Date constructor is interpreted, including the fact of a conversion of a time value to UTC.


Section 15.9.1.9 defines the conversions between local time and UTC time, and states that these conversions are not necessarily inverses of each other.


The formula for this conversion is as follows:

UTC( t ) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)
If you follow this through for the start of DST, you can see how the hour gets subtracted.  This example is for Pacific time, so the actual date isn't changed.  Start with:

t = <Sun Mar 13 02:00:00 Pacific 2011>

LocalTZA = -8

The expression t - LocalTZA occurs twice in this equation; it evaluates to <Sun Mar 13 10:00:00 UTC 2011>. This is the exact moment when DST starts in the Pacific time zone. This is the key fact during conversion of this time to UTC:

UTC( <Sun Mar 13 02:00:00 Pacific 2011> )

   = <Sun Mar 13 02:00:00 Pacific 2011> - LocalTZA - DaylightSavingTA( <Sun Mar 13 02:00:00 Pacific 2011> - LocalTZA )

   = <Sun Mar 13 10:00:00 UTC 2011> - DaylightSavingTA( <Sun Mar 13 10:00:00 UTC 2011> )

   = <Sun Mar 13 10:00:00 UTC 2011> - 1

   = <Sun Mar 13 9:00:00 UTC 2011>


Properties

Article ID: 2410734 - Last Review: Nov 24, 2016 - Revision: 1

Feedback