From 00b8bc25c4e943bd2770b60ba0f38535c3cf4bf4 Mon Sep 17 00:00:00 2001 From: Jungshik Shin Date: Fri, 20 Jan 2017 15:20:54 -0800 Subject: [PATCH] Make LocalTZA take 't' and 'isUTC', Drop DSTA(t). Currently, LocalTimezoneAdjustment is assumed to be constant across time zone rule changes and does not take any argument. Daylight Savings Time Adjustment does take an argument t. DSTA(t) can 'absorb' the standard time zone offset changes (e.g. Europe/Moscow changed the standard time zone offset multiple times in the last decade.). However, the spec stipulates that it should only reprsent an additional adjustment necessary when DST is in effect. In practice, at least two implementations (Spidermonkey/Firefox and JSC/Safari) do not follow the spec to the letter to produce results expected by users across time zone rule changes. This PR revises LocalTZA to accept two arguments, 't' and 'isUTC' and drop DaylightSavingsTimeAdjustment(t). When isUTC is true, LocalTZA interprets 't' as a time value representing UTC and gives a time zone offset in effect at time t for the local time zone (for US ET, it'd be 4*msPerHour in summer and 5*msPerHour in winter). When isUTC is false, 't' is interpreted as local time value and gives a time zone offset in effect at t = t_local. It's also specified that LocalTZA(t = t_local, false) will return the offset *before* the transition when t_local is wall time repeating multiple times at a negative transition (e.g. fall backward) or skipped wall time at a positive time zone transition (e.g. spring forward). This is to get rid of an ambiguity in handling a time zone offset transition. Due to the ambiguity, different implemenations have different behaviors and some implementations have changed their behavior over the time. UTC(t) and Localtime(t) are reformulated with LocalTZA(t = t_local, false) and LocalTZA(t = t_UTC, true). Will fix #725. In the future, it might as well be considered to add an option to specify the behavior to handle skipped or repeated wall time. See [1] and [2]. [1] ICU Calendar API has skipped wall time option (https://goo.gl/h0bP26) and repeated wall time option (https://goo.gl/Q1VX3j). [2] Python proposal to handle skipped/repeated time: https://www.python.org/dev/peps/pep-0495/ --- spec.html | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/spec.html b/spec.html index c28b5d38b4..89d109fa0c 100644 --- a/spec.html +++ b/spec.html @@ -26762,44 +26762,43 @@

Week Day

-

Local Time Zone Adjustment

-

An implementation of ECMAScript is expected to determine the local time zone adjustment. The local time zone adjustment is a value LocalTZA measured in milliseconds which when added to UTC represents the local standard time. Daylight saving time is not reflected by LocalTZA.

+

LocalTimeZoneAdjustment ( _t_, _isUTC_ )

+

An implementation of ECMAScript is expected to determine the local time zone adjustment with respect to UTC using the best available information on time zones.

+

When _isUTC_ is true, LocalTZA( _t_, true ) is the offset of the local time zone from UTC measured in milliseconds at time represented by time value _t_ (UTC). When it is added to _t_ (UTC), it yields the local time.

+

When _isUTC_ is false, LocalTZA( _t_, false ) is the offset of the local time zone from UTC measured in milliseconds at local time represented by time value _t_local = _t_. When it is subtracted from the local time _t_local, it yields the corresponding UTC.

+

When _t_local represents wall time repeating multiple times at a negative time zone transition (e.g. when the daylight savings time ends or the time zone adjustment is increased) or skipped wall time at a positive time zone transitions (e.g. when the daylight savings time starts or the time zone adjustment is decreased), _t_local must be interpreted with the time zone adjustment after the transition.

It is recommended that implementations use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

+

1:30 AM on November 5, 2017 in America/New_York is repeated twice (fall backward), but it must be interpreted as 1:30 AM UTC-05 instead of 1:30 AM UTC-04. LocalTZA(TimeClip(MakeDate(MakeDay(2017, 10, 5), MakeTime(1, 30, 0, 0))), false) is -5 × msPerHour.

+

2:30 AM on March 12, 2017 in America/New_York does not exist, but it must be interpreted as 2:30 AM UTC-04. LocalTZA(TimeClip(MakeDate(MakeDay(2017, 2, 12), MakeTime(2, 30, 0, 0))), false) is -4 × msPerHour.

.
- -

Daylight Saving Time Adjustment

-

An implementation-dependent algorithm using best available information on time zones to determine the local daylight saving time adjustment DaylightSavingTA(_t_), measured in milliseconds. An implementation of ECMAScript is expected to make its best effort to determine the local daylight saving time adjustment.

- -

It is recommended that implementations use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

-
-
- -

LocalTime ( _t_ )

The abstract operation LocalTime with argument _t_ converts _t_ from UTC to local time by performing the following steps:

- 1. Return _t_ + LocalTZA + DaylightSavingTA(_t_). + 1. Return _t_ + LocalTZA(_t_, true). + +

Two different time values (_t_ (UTC)) are converted to the same local time tlocal at a negative time zone transition when there are repeated times (e.g. the daylight savings time ends or the time zone adjustment is decreased.).

+
- +

UTC ( _t_ )

The abstract operation UTC with argument _t_ converts _t_ from local time to UTC. It performs the following steps:

- 1. Return _t_ - LocalTZA - DaylightSavingTA(_t_ - LocalTZA). + 1. Return _t_ - LocalTZA( _t_ , false) -

UTC(LocalTime(_t_)) is not necessarily always equal to _t_.

+

UTC(LocalTime(_t_)) is not necessarily always equal to _t_. LocalTime(UTC(_t_local)) is not necessarily always equal to _t_local, either.

- +

Hours, Minutes, Second, and Milliseconds

The following abstract operations are useful in decomposing time values:

@@ -26816,7 +26815,7 @@

Hours, Minutes, Second, and Milliseconds

msPerHour = 3600000 = msPerMinute × MinutesPerHour
- +

MakeTime ( _hour_, _min_, _sec_, _ms_ )

The abstract operation MakeTime calculates a number of milliseconds from its four arguments, which must be ECMAScript Number values. This operator functions as follows:

@@ -26831,7 +26830,7 @@

MakeTime ( _hour_, _min_, _sec_, _ms_ )

- +

MakeDay ( _year_, _month_, _date_ )

The abstract operation MakeDay calculates a number of days from its three arguments, which must be ECMAScript Number values. This operator functions as follows:

@@ -26847,7 +26846,7 @@

MakeDay ( _year_, _month_, _date_ )

- +

MakeDate ( _day_, _time_ )

The abstract operation MakeDate calculates a number of milliseconds from its two arguments, which must be ECMAScript Number values. This operator functions as follows:

@@ -26857,7 +26856,7 @@

MakeDate ( _day_, _time_ )

- +

TimeClip ( _time_ )

The abstract operation TimeClip calculates a number of milliseconds from its argument, which must be an ECMAScript Number value. This operator functions as follows:

@@ -26873,7 +26872,7 @@

TimeClip ( _time_ )

- +

Date Time String Format

ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 Extended Format. The format is as follows: `YYYY-MM-DDTHH:mm:ss.sssZ`

@@ -27001,7 +27000,7 @@

Date Time String Format

There exists no international standard that specifies abbreviations for civil time zones like CET, EST, etc. and sometimes the same abbreviation is even used for two very different time zones. For this reason, ISO 8601 and this format specifies numeric representations of date and time.

- +

Extended Years

ECMAScript requires the ability to specify 6 digit years (extended years); approximately 285,426 years, either forward or backward, from 01 January, 1970 UTC. To represent years before 0 or after 9999, ISO 8601 permits the expansion of the year representation, but only by prior agreement between the sender and the receiver. In the simplified ECMAScript format such an expanded year representation shall have 2 extra year digits and is always prefixed with a + or - sign. The year 0 is considered positive and hence prefixed with a + sign.