From 047479144df393e96d8d1d495875f70cc3c01c6a Mon Sep 17 00:00:00 2001 From: Justin Grant Date: Sun, 11 Jun 2023 21:22:59 -0700 Subject: [PATCH] Editorial: Refactor time zone identifier spec text This commit builds on the new ECMA-262 text for time zone identifiers that was introduced in https://github.com/tc39/ecma262/pull/3035. This commit adds Temporal-specific AOs and makes a handful of edits to ECMA-262 AOs for changes that didn't apply to %Date% but that will be required after Temporal is merged into ECMA-262. This commit also revises the ASCII-case-insensitive section to address feedback from ECMA-262 editors before this text was removed from https://github.com/tc39/ecma262/pull/3035: * Remove the "sequence of code points" info because only Strings seemed to use these definitions. * Minor wordsmithing, e.g. "string value" => "String" --- package-lock.json | 14 +-- package.json | 2 +- spec/intl.html | 187 ++++++++++++++++++++++++++++------------ spec/mainadditions.html | 84 +++++++++++++++--- spec/temporal.html | 6 +- spec/timezone.html | 148 ++++++++++--------------------- 6 files changed, 265 insertions(+), 176 deletions(-) diff --git a/package-lock.json b/package-lock.json index fa8ffd313a..8b64fdad77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "BSD-3-Clause", "devDependencies": { - "@tc39/ecma262-biblio": "=2.1.2576", + "@tc39/ecma262-biblio": "=2.1.2577", "@typescript-eslint/eslint-plugin": "^5.59.9", "@typescript-eslint/parser": "^5.59.9", "ecmarkup": "^17.0.0", @@ -323,9 +323,9 @@ } }, "node_modules/@tc39/ecma262-biblio": { - "version": "2.1.2576", - "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2576.tgz", - "integrity": "sha512-GG+y00NrCcRy6oN2/4t50xaKXE0FA76ZuVAw0NjhjVS/yboxkN0QrPUMUY6OI9TzzuTM0sazRJOp6qsOJ0Kerg==", + "version": "2.1.2577", + "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2577.tgz", + "integrity": "sha512-Grv210DOA5HGNo56tHAxP4ScujqG7NRMWIraGNSxtTxKxUdcTAubrcglqa6bbKNsTK+Dg2Bew8cSr06fJX827g==", "dev": true }, "node_modules/@tootallnate/once": { @@ -3062,9 +3062,9 @@ } }, "@tc39/ecma262-biblio": { - "version": "2.1.2576", - "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2576.tgz", - "integrity": "sha512-GG+y00NrCcRy6oN2/4t50xaKXE0FA76ZuVAw0NjhjVS/yboxkN0QrPUMUY6OI9TzzuTM0sazRJOp6qsOJ0Kerg==", + "version": "2.1.2577", + "resolved": "https://registry.npmjs.org/@tc39/ecma262-biblio/-/ecma262-biblio-2.1.2577.tgz", + "integrity": "sha512-Grv210DOA5HGNo56tHAxP4ScujqG7NRMWIraGNSxtTxKxUdcTAubrcglqa6bbKNsTK+Dg2Bew8cSr06fJX827g==", "dev": true }, "@tootallnate/once": { diff --git a/package.json b/package.json index e84e0b727e..c3918f5973 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "main": "polyfill/lib/index.mjs", "devDependencies": { - "@tc39/ecma262-biblio": "=2.1.2576", + "@tc39/ecma262-biblio": "=2.1.2577", "@typescript-eslint/eslint-plugin": "^5.59.9", "@typescript-eslint/parser": "^5.59.9", "ecmarkup": "^17.0.0", diff --git a/spec/intl.html b/spec/intl.html index 087d5e3d72..823c497d5e 100644 --- a/spec/intl.html +++ b/spec/intl.html @@ -8,6 +8,7 @@

Amendments to the ECMAScript® 2023 Internationalization API Specification This section lists amendments which must be made to ECMA-402, the ECMAScript® 2023 Internationalization API Specification. Text to be added is marked like this, and text to be deleted is marked like this. + Blocks of unmodified text between modified sections are marked by [...].

This text is based on top of the ECMA-402 spec text from commit eb81befe8b739f976a3d6e68ec567302c4e217f0. @@ -40,15 +41,89 @@

Cas - -

Time Zone Names

+ + +

Use of the IANA Time Zone Database

- + This section replaces the Time Zone Names section in ECMA-402. +

+ Implementations that adopt the ECMAScript Internationalization API Specification are time zone aware: they use the IANA Time Zone Database https://www.iana.org/time-zones/ to supply time zone identifiers and data used in ECMAScript calculations and formatting. + This section defines how the IANA Time Zone Database should be used by time zone aware implementations. +

+

+ Except as overridden by AvailableNamedTimeZoneIdentifiers, each Zone in the IANA Time Zone Database must be a primary time zone identifier and each Link name in the IANA Time Zone Database must be a non-primary time zone identifier. + No String may be an available named time zone identifier unless it is a Zone name or a Link name in the IANA Time Zone Database. + Available named time zone identifiers returned by ECMAScript built-in objects must use the casing found in the IANA Time Zone Database. +

+

+ In the IANA Time Zone Database, the UTC time zone is represented by the Zone *"Etc/UTC"* which is distinct from the Zone *"Etc/GMT"*. + For historical reasons, ECMAScript uses *"UTC"* as the primary identifier for the former Zone and does not recognize the latter Zone as distinct, instead requiring *"Etc/UTC"*, *"Etc/GMT"*, and *"GMT"* (if available) to be non-primary identifiers that resolve to *"UTC"*. + This is the only deviation from the IANA Time Zone Database that is required of a time zone aware ECMAScript implementation. +

+

+ The IANA Time Zone Database is typically updated between five and ten times per year. + These updates may add new Zone or Link names, may change Zones to Links, and may change the UTC offsets and transitions associated with any Zone. + ECMAScript implementations are recommended to include updates to the IANA Time Zone Database as soon as possible. + Such prompt action ensures that ECMAScript programs can accurately perform time-zone-sensitive calculations and can use newly-added available named time zone identifiers supplied by external input or the host environment. +

+

+ If implementations revise time zone information during the lifetime of an agent, then which identifiers are supported, the primary time zone identifier associated with any identifier, and the UTC offsets and transitions associated with any Zone, must be consistent with results previously observed by that agent. + Due to the complexity of supporting this requirement, it is recommended that implementations maintain a fully consistent copy of the IANA Time Zone Database for the lifetime of each agent. +

+ +

This section complements but does not supersede .

+ +

- defines a set of abstract operations concerning the names of supported time zones. - This section introduces additional requirements on these operations for implementations. + The IANA Time Zone Database offers build options that affect which time zone identifiers are primary. + The default build options merge different countries' time zones, for example *"Atlantic/Reykjavik"* being a Link to the Zone *"Africa/Abidjan"*. + Geographically and politically distinct locations are likely to introduce divergent time zone rules in a future version of the IANA Time Zone Database. + Therefore, it is recommended that ECMAScript implementations instead use build options such as PACKRATDATA=backzone PACKRATLIST=zone.tab or a similar alternative that ensures at least one primary identifier for each ISO 3166-1 Alpha-2 country code.

-
+ + + +

AvailableNamedTimeZoneIdentifiers ( ): a List of Time Zone Identifier Records

+
+
description
+
+ Its result describes all available named time zone identifiers in this implementation, as well as the primary time zone identifier corresponding to each available named time zone identifier. + The List is ordered according to the [[Identifier]] field of each Time Zone Identifier Record. +
+
redefinition
+
true
+
+

This definition supersedes the definition provided in .

+ + 1. Let _identifiers_ be a List containing the String value of each Zone or Link name in the IANA Time Zone Database. + 1. Assert: No element of _identifiers_ is an ASCII-case-insensitive match for any other element. + 1. Assert: Every element of _identifiers_ identifies a Zone or Link name in the IANA Time Zone Database. + 1. Set _identifiers_ to SortStringListByCodeUnit(_identifiers_). + 1. Let _result_ be a new empty List. + 1. For each element _identifier_ of _identifiers_, do + 1. Let _primary_ be _identifier_. + 1. If _identifier_ is a non-primary time zone identifier and _identifier_ is not *"UTC"*, then + 1. Set _primary_ to the name of the primary time zone identifier that _identifier_ resolves to, according to the rules for resolving Link names in the IANA Time Zone Database. + 1. NOTE: An implementation may need to resolve _identifier_ iteratively to obtain the primary time zone identifier. + 1. If _primary_ is one of *"Etc/UTC"*, *"Etc/GMT"*, or *"GMT"*, set _primary_ to *"UTC"*. + 1. Let _record_ be the Time Zone Identifier Record { [[Identifier]]: _identifier_, [[PrimaryIdentifier]]: _primary_ }. + 1. Append _record_ to _result_. + 1. Assert: _result_ contains a Time Zone Identifier Record _r_ such that _r_.[[Identifier]] is *"UTC"* and _r_.[[PrimaryIdentifier]] is *"UTC"*. + 1. Return _result_. + + + + Time zone identifiers in the IANA Time Zone Database can change over time. + At a minimum, it is recommended that implementations limit changes to the result of AvailableNamedTimeZoneIdentifiers to the changes allowed by GetAvailableNamedTimeZoneIdentifier, for the lifetime of the surrounding agent. + Due to the complexity of supporting these recommendations, it is recommended that the result of AvailableNamedTimeZoneIdentifiers remains the same for the lifetime of the surrounding agent. + +
+
+
+ + + +

Time Zone Names

The ECMAScript 2023 Internationalization API Specification identifies time zones using the Zone and Link names of the IANA Time Zone Database. Their canonical form is the corresponding Zone name in the casing used in the IANA Time Zone Database except as specifically overridden by CanonicalizeTimeZoneName. @@ -58,70 +133,71 @@

Time Zone Namesonly such names), and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations. However, the set of combinations of time zone name and language tag for which localized time zone names are available is implementation dependent.

- - -

IsValidTimeZoneName ( _timeZone_ )

+ +

IsValidTimeZoneName ( _timeZone_ )

-

- The abstract operation IsValidTimeZoneName takes argument _timeZone_, a String value, and verifies that it represents a valid Zone or Link name of the IANA Time Zone Database. -

+

+ The abstract operation IsValidTimeZoneName takes argument _timeZone_, a String value, and verifies that it represents a valid Zone or Link name of the IANA Time Zone Database. +

- - 1. If one of the Zone or Link names of the IANA Time Zone Database is an ASCII-case-insensitive match of _timeZone_, return *true*. - 1. If _timeZone_ is an ASCII-case-insensitive match of *"UTC"*, return *true*. - 1. Return *false*. - -
-
+ + 1. If one of the Zone or Link names of the IANA Time Zone Database is an ASCII-case-insensitive match of _timeZone_, return *true*. + 1. If _timeZone_ is an ASCII-case-insensitive match of *"UTC"*, return *true*. + 1. Return *false*. + + - +

CanonicalizeTimeZoneName ( - _timeZone_: a String value that is a validan available time zone name as verified by IsValidTimeZoneNameIsAvailableTimeZoneName, + _timeZone_: a String value that is a valid time zone name as verified by IsValidTimeZoneName, )

description
It returns the canonical and case-regularized form of _timeZone_.
-
redefinition
-
true
- 1. Let _ianaTimeZone_ be the String value of the Zone or Link name of the IANA Time Zone Database that is an ASCII-case-insensitive match of _timeZone_. 1. If _ianaTimeZone_ is a Link name, let _ianaTimeZone_ be the String value of the corresponding Zone name as specified in the file backward of the IANA Time Zone Database. 1. If _ianaTimeZone_ is *"Etc/UTC"* or *"Etc/GMT"*, return *"UTC"*. 1. Return _ianaTimeZone_. +
- -

This definition supersedes the definition provided in .

-
+ +

DefaultTimeZone ( ): a String

+ +
+
description
+
It returns a String value representing the host environment's current time zone, which is a valid () and canonicalized () time zone name.
+
+ +

+ This definition supersedes the definition provided in es2024, . +

- - -

- AvailableTimeZones ( - ): a List of Strings -

-
-
description
-
The returned List is a sorted List of supported Zone and Link names in the IANA Time Zone Database.
-
redefinition
-
true
-
- - 1. Let _timeZones_ be a List containing the String value of each Zone or Link name in the IANA Time Zone Database that is supported by the implementation. - 1. Assert: _timeZones_ contains *"UTC"*. - 1. Assert: _timeZones_ does not contain any element that does not identify a Zone or Link name in the IANA Time Zone Database. - 1. Return SortStringListByCodeUnit(_timeZones_). - + +

+ AvailableTimeZones ( + ): a List of Strings +

+
+
description
+
The returned List is a sorted List of supported Zone and Link names in the IANA Time Zone Database.
+
+ + 1. Let _timeZones_ be a List containing the String value of each Zone or Link name in the IANA Time Zone Database that is supported by the implementation. + 1. Assert: _timeZones_ contains *"UTC"*. + 1. Assert: _timeZones_ does not contain any element that does not identify a Zone or Link name in the IANA Time Zone Database. + 1. Return SortStringListByCodeUnit(_timeZones_). + -

This definition supersedes the definition provided in .

-
-
+

This definition supersedes the definition provided in [removed].

+
+

Abstract Operations

@@ -244,13 +320,14 @@

InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ [ , _ 1. If _toLocaleStringTimeZone_ is present, then 1. Set _timeZone_ to _toLocaleStringTimeZone_. 1. Else, - 1. Set _timeZone_ to DefaultTimeZone(). + 1. Set _timeZone_ to SystemTimeZoneIdentifier(). 1. Else, 1. If _toLocaleStringTimeZone_ is present, throw a *TypeError* exception. 1. Set _timeZone_ to ? ToString(_timeZone_). - 1. If the result of IsValidTimeZoneName(_timeZone_)IsAvailableTimeZoneName(_timeZone_) is *false*, then + 1. Let _timeZoneIdentifierRecord_ be GetAvailableNamedTimeZoneIdentifier(_timeZone_). + 1. If the result of IsValidTimeZoneName(_timeZone_) is *false*_timeZoneIdentifierRecord_ is ~empty~, then 1. Throw a *RangeError* exception. - 1. Set _timeZone_ to CanonicalizeTimeZoneName(_timeZone_). + 1. Set _timeZone_ to CanonicalizeTimeZoneName(_timeZone_)_timeZoneIdentifierRecord_.[[PrimaryIdentifier]]. 1. Set _dateTimeFormat_.[[TimeZone]] to _timeZone_. 1. Let _formatOptions_ be a new Record. 1. Set _formatOptions_.[[hourCycle]] to _hc_. @@ -1275,7 +1352,8 @@

Intl.DateTimeFormat.prototype.resolvedOptions ( )

- In this version of the ECMAScript 2023 Internationalization API, the *"timeZone"* property will be the name of the default time zone if no *"timeZone"* property was provided in the options object provided to the Intl.DateTimeFormat constructor. The first edition left the *"timeZone"* property *undefined* in this case. + In this version of the ECMAScript Internationalization API, the *"timeZone"* property will be the name of the system time zone identifier if no *"timeZone"* property was provided in the options object provided to the Intl.DateTimeFormat constructor. + The first edition left the *"timeZone"* property *undefined* in this case. @@ -2465,8 +2543,9 @@

Temporal.ZonedDateTime.prototype.toLocaleString ( [ _locales_ [ , _options_ 1. Let _dateTimeFormat_ be ! OrdinaryCreateFromConstructor(%DateTimeFormat%, %DateTimeFormat.prototype%, « [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[FractionalSecondDigits]], [[TimeZoneName]], [[HourCycle]], [[Pattern]], [[BoundFormat]] »). 1. Let _timeZone_ be ? ToTemporalTimeZoneIdentifier(_zonedDateTime_.[[TimeZone]]). 1. If IsTimeZoneOffsetString(_timeZone_) is *true*, throw a *RangeError* exception. - 1. If IsAvailableTimeZoneName(_timeZone_) is *false*, throw a *RangeError* exception. - 1. Set _timeZone_ to CanonicalizeTimeZoneName(_timeZone_). + 1. Let _timeZoneIdentifierRecord_ be GetAvailableNamedTimeZoneIdentifier(_timeZone_). + 1. If _timeZoneIdentifierRecord_ is ~empty~, throw a RangeError exception. + 1. Set _timeZone_ to _timeZoneIdentifierRecord_.[[PrimaryIdentifier]]. 1. Perform ? InitializeDateTimeFormat(_dateTimeFormat_, _locales_, _options_, _timeZone_). 1. Let _calendar_ be ? ToTemporalCalendarIdentifier(_zonedDateTime_.[[Calendar]]). 1. If _calendar_ is not *"iso8601"* and not equal to _dateTimeFormat_.[[Calendar]], then diff --git a/spec/mainadditions.html b/spec/mainadditions.html index 2997428e6f..7c1ff6264f 100644 --- a/spec/mainadditions.html +++ b/spec/mainadditions.html @@ -8,6 +8,7 @@

Amendments to the ECMAScript® 2023 Language Specification

This section lists amendments which must be made to ECMA-262, the ECMAScript® 2023 Language Specification, other than the addition of the new sections specifying the Temporal object and everything related to it. Text to be added is marked like this, and text to be deleted is marked like this. + Blocks of unmodified text between modified sections are marked by [...].

@@ -16,22 +17,17 @@

- This section intends to move the definitions of ASCII-uppercase, ASCII-lowercase, and ASCII-case-insensitive match from ECMA-402 into ECMA-262, after the definition of the ASCII word characters, and generalizes the former two definitions to cover sequences of code points. + This section intends to move the definitions of ASCII-uppercase, ASCII-lowercase, and ASCII-case-insensitive match from ECMA-402 into ECMA-262, after the definition of the ASCII word characters. + The definitions include minor editorial changes from ECMA-402 to address feedback from the ECMA-262 editors.

[...]

-

- The ASCII-uppercase of a String value _S_ is the String value derived from _S_ by replacing each occurrence of an ASCII lowercase letter code unit (0x0061 through 0x007A, inclusive) with the corresponding ASCII uppercase letter code unit (0x0041 through 0x005A, inclusive) while preserving all other code units. The ASCII-uppercase of a sequence of Unicode code points _A_ is the sequence of code points derived from _A_ by replacing each occurrence of an ASCII lowercase letter code point (U+0061 through U+007A, inclusive) with the corresponding ASCII uppercase letter code point (U+0041 through U+005A, inclusive) while preserving all other code points. -

-

- The ASCII-lowercase of a String value _S_ is the String value derived from _S_ by replacing each occurrence of an ASCII uppercase letter code unit (0x0041 through 0x005A, inclusive) with the corresponding ASCII lowercase letter code unit (0x0061 through 0x007A, inclusive) while preserving all other code units. The ASCII-lowercase of a sequence of Unicode code points _A_ is the sequence of code points derived from _A_ by replacing each occurrence of an ASCII uppercase letter code point (U+0041 through U+005A, inclusive) with the corresponding ASCII lowercase letter code point (U+0061 through U+007A, inclusive) while preserving all other code points. -

-

- A String value _A_ is an ASCII-case-insensitive match for String value _B_ if the ASCII-uppercase of _A_ is exactly the same sequence of code units as the ASCII-uppercase of _B_. A sequence of Unicode code points _A_ is an ASCII-case-insensitive match for _B_ if _B_ is an ASCII-case-insensitive match for ! CodePointsToString(_A_). -

+

The ASCII-uppercase of a String _S_ is the String derived from _S_ by replacing each occurrence of an ASCII lowercase letter code unit (0x0061 through 0x007A, inclusive) with the corresponding ASCII uppercase letter code unit (0x0041 through 0x005A, inclusive) while preserving all other code units.

+

The ASCII-lowercase of a String _S_ is the String derived from _S_ by replacing each occurrence of an ASCII uppercase letter code unit (0x0041 through 0x005A, inclusive) with the corresponding ASCII lowercase letter code unit (0x0061 through 0x007A, inclusive) while preserving all other code units.

+

A String _A_ is an ASCII-case-insensitive match for a String _B_ if the ASCII-lowercase of _A_ is the ASCII-lowercase of _B_.

@@ -212,6 +208,74 @@

+ +

Overview of Date Objects and Definitions of Abstract Operations

+ +

[...]

+ + +

Time Zone Identifiers

+ +

+ Time zones in ECMAScript are represented by time zone identifiers, which are Strings composed entirely of code units in the inclusive interval from 0x0000 to 0x007F0x0021 to 0x007E. + Time zones supported by an ECMAScript implementation may be available named time zones, represented by the [[Identifier]] field of the Time Zone Identifier Records returned by AvailableNamedTimeZoneIdentifiers, or offset time zones, represented by Strings for which IsTimeZoneOffsetString returns *true*. + Time zone identifiers are compared using ASCII-case-insensitive comparisons. +

+

+ A primary time zone identifier is the preferred identifier for an available named time zone. + A non-primary time zone identifier is an identifier for an available named time zone that is not a primary time zone identifier. + An available named time zone identifier is either a primary time zone identifier or a non-primary time zone identifier. + Each available named time zone identifier is associated with exactly one available named time zone. + Each available named time zone is associated with exactly one primary time zone identifier and zero or more non-primary time zone identifiers. +

+

+ ECMAScript implementations must support an available named time zone with the identifier *"UTC"*, which must be the primary time zone identifier for the UTC time zone. + In addition, implementations may support any number of other available named time zones. +

+

+ Implementations that follow the requirements for time zones as described in the ECMA-402 Internationalization API specification are called time zone aware. + Time zone aware implementations must support available named time zones corresponding to the Zone and Link names of the IANA Time Zone Database, and only such names. + In time zone aware implementations, a primary time zone identifier is a Zone name, and a non-primary time zone identifier is a Link name, respectively, in the IANA Time Zone Database except as specifically overridden by AvailableNamedTimeZoneIdentifiers as specified in the ECMA-402 specification. + Implementations that do not support the entire IANA Time Zone Database are still recommended to use IANA Time Zone Database names as identifiers to represent time zones. +

+
+ + +

AvailableNamedTimeZoneIdentifiers ( ): a List of Time Zone Identifier Records

+
+
description
+
+ Its result describes all available named time zone identifiers in this implementation, as well as the primary time zone identifier corresponding to each available named time zone identifier. + The List is ordered according to the [[Identifier]] field of each Time Zone Identifier Record. +
+
+

+ Time zone aware implementations, including all implementations that implement the ECMA-402 Internationalization API, must implement the AvailableNamedTimeZoneIdentifiers abstract operation as specified in the ECMA-402 specification. + For implementations that are not time zone aware, AvailableNamedTimeZoneIdentifiers performs the following steps when called: +

+ + 1. If the implementation does not include local political rules for any time zones, then + 1. Return « the Time Zone Identifier Record { [[Identifier]]: *"UTC"*, [[PrimaryIdentifier]]: *"UTC"* } ». + 1. Let _identifiers_ be the List of unique available named time zone identifiers. + 1. Sort _identifiers_ into the same order as if an Array of the same values had been sorted using %Array.prototype.sort% with *undefined* as the argument. + 1. Set _identifiers_ to SortStringListByCodeUnit(_identifiers_). + 1. Let _result_ be a new empty List. + 1. For each element _identifier_ of _identifiers_, do + 1. Let _primary_ be _identifier_. + 1. If _identifier_ is a non-primary time zone identifier in this implementation and _identifier_ is not *"UTC"*, then + 1. Set _primary_ to the primary time zone identifier associated with _identifier_. + 1. NOTE: An implementation may need to resolve _identifier_ iteratively to obtain the primary time zone identifier. + 1. Let _record_ be the Time Zone Identifier Record { [[Identifier]]: _identifier_, [[PrimaryIdentifier]]: _primary_ }. + 1. Append _record_ to _result_. + 1. Assert: _result_ contains a Time Zone Identifier Record _r_ such that _r_.[[Identifier]] is *"UTC"* and _r_.[[PrimaryIdentifier]] is *"UTC"*. + 1. Return _result_. + +
+ +

[...]

+ +
+

The Date Constructor

diff --git a/spec/temporal.html b/spec/temporal.html index 3b2bc25a68..454a9a47b3 100644 --- a/spec/temporal.html +++ b/spec/temporal.html @@ -97,7 +97,7 @@

Temporal.Now.timeZoneId ( )

This function performs the following steps when called:

- 1. Return DefaultTimeZone(). + 1. Return SystemTimeZoneIdentifier().
@@ -250,7 +250,7 @@

SystemInstant ( )

SystemDateTime ( _temporalTimeZoneLike_, _calendarLike_ )

1. If _temporalTimeZoneLike_ is *undefined*, then - 1. Let _timeZone_ be DefaultTimeZone(). + 1. Let _timeZone_ be SystemTimeZoneIdentifier(). 1. Else, 1. Let _timeZone_ be ? ToTemporalTimeZoneSlotValue(_temporalTimeZoneLike_). 1. Let _calendar_ be ? ToTemporalCalendarSlotValue(_calendarLike_). @@ -263,7 +263,7 @@

SystemDateTime ( _temporalTimeZoneLike_, _calendarLike_ )

SystemZonedDateTime ( _temporalTimeZoneLike_, _calendarLike_ )

1. If _temporalTimeZoneLike_ is *undefined*, then - 1. Let _timeZone_ be DefaultTimeZone(). + 1. Let _timeZone_ be SystemTimeZoneIdentifier(). 1. Else, 1. Let _timeZone_ be ? ToTemporalTimeZoneSlotValue(_temporalTimeZoneLike_). 1. Let _calendar_ be ? ToTemporalCalendarSlotValue(_calendarLike_). diff --git a/spec/timezone.html b/spec/timezone.html index f02fbfd02b..1825010aee 100644 --- a/spec/timezone.html +++ b/spec/timezone.html @@ -5,99 +5,6 @@

Temporal.TimeZone Objects

A Temporal.TimeZone object is an Object referencing a time zone.

- -

Time Zone Names

- -

- An ECMAScript implementation must support a number of built-in time zones. - At a minimum, implementations must support a built-in time zone named *"UTC"*. - If the return value _tz_ of DefaultTimeZone is different from *"UTC"*, and IsTimeZoneOffsetString(_tz_) is *false*, then implementations must support that time zone as a built-in time zone as well. - In addition, implementations may support any number of other built-in time zones. -

-

- Built-in time zones may be named time zones, represented by Strings for which IsAvailableTimeZoneName returns *true*. - They may also be offset time zones, represented by Strings for which IsTimeZoneOffsetString returns *true*. -

-

- The `Temporal.TimeZone` constructor, when called with the name of a built-in time zone as the argument, will return a valid `Temporal.TimeZone` object. - When called with any other string, it will throw a *RangeError* exception. -

-

- An ECMAScript implementation that includes the ECMA-402 Internationalization API must define built-in named time zones in correspondence with the Zone and Link names of the IANA Time Zone Database (and only such names) and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations as specified in the ECMA-402 specification. - Other implementations are encouraged to do the same. -

- - -

- IsAvailableTimeZoneName ( - _timeZone_: a String, - ): a Boolean -

-
-
description
-
The returned value is *true* if _timeZone_ is an ASCII-case-insensitive match for a supported time zone name, and *false* otherwise.
-
-

- Once IsAvailableTimeZoneName(_timeZone_) has returned *true*, for the lifetime of the surrounding agent, IsAvailableTimeZoneName(_variant_) must return *true* if _variant_ is an ASCII-case-insensitive match for either _timeZone_ or CanonicalizeTimeZoneName(_timeZone_). -

- - - 1. Let _timeZones_ be AvailableTimeZones(). - 1. For each String _candidate_ in _timeZones_, do - 1. If _timeZone_ is an ASCII-case-insensitive match for _candidate_, return *true*. - 1. Return *false*. - -
- - -

- CanonicalizeTimeZoneName ( - _timeZone_: a String that is a valid time zone name as verified by IsAvailableTimeZoneName, - ) -

-
-
description
-
It returns the canonical and case-regularized form of _timeZone_.
-
- -

- An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the CanonicalizeTimeZoneName abstract operation as specified in the ECMA-402 specification. -

-

- The minimum implementation of CanonicalizeTimeZoneName for ECMAScript implementations that do not include local political rules for any time zones performs the following steps when called: -

- - - 1. Assert: _timeZone_ is an ASCII-case-insensitive match for *"UTC"*. - 1. Return *"UTC"*. - -
- - -

- AvailableTimeZones ( - ): a List of Strings -

-
-
description
-
The returned List is a sorted List of identifiers for time zones for which the implementation includes local political rules, and aliases for those identifiers.
-
- -

- An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the AvailableTimeZones abstract operation as specified in the ECMA-402 specification. - If an ECMAScript implementation does not include the ECMA-402 API the following specification of the AvailableTimeZones abstract operation is used. -

- - 1. Let _timeZones_ be the List of String values representing time zones supported by the implementation. - 1. Assert: _timeZones_ contains *"UTC"*. - 1. Return SortStringListByCodeUnit(_timeZones_). - -

- For example, an ECMAScript implementation that does not include local political rules for any time zone could return a List with the single String *"UTC"* here. -

-
-
-

The Temporal.TimeZone Constructor

The Temporal.TimeZone constructor:

@@ -126,9 +33,9 @@

Temporal.TimeZone ( _identifier_ )

1. Throw a *TypeError* exception. 1. Set _identifier_ to ? ToString(_identifier_). 1. If IsTimeZoneOffsetString(_identifier_) is *false*, then - 1. If IsAvailableTimeZoneName(_identifier_) is *false*, then - 1. Throw a *RangeError* exception. - 1. Set _identifier_ to ! CanonicalizeTimeZoneName(_identifier_). + 1. Let _timeZoneIdentifierRecord_ be GetAvailableNamedTimeZoneIdentifier(_identifier_). + 1. If _timeZoneIdentifierRecord_ is ~empty~, throw a *RangeError* exception. + 1. Set _identifier_ to _timeZoneIdentifierRecord_.[[PrimaryIdentifier]]. 1. Return ? CreateTemporalTimeZone(_identifier_, NewTarget).
@@ -385,6 +292,19 @@

Properties of Temporal.TimeZone Instances

Abstract operations

+ + In ECMA-262, many time-zone-related sections and abstract operations are contained in the Date Objects section of the specification. + Now that ECMAScript has a built-in %Temporal.TimeZone% object, it may be appropriate to move those sections here, for example: +
    +
  • Time Zone Identifiers
  • +
  • AvailableNamedTimeZoneIdentifiers
  • +
  • SystemTimeZoneIdentifier
  • +
  • IsTimeZoneOffsetString
  • +
  • GetNamedTimeZoneEpochNanoseconds
  • +
  • GetNamedTimeZoneOffsetNanoseconds
  • +
+
+

CreateTemporalTimeZone ( @@ -403,7 +323,7 @@

1. Set _object_.[[Identifier]] to ~empty~. 1. Set _object_.[[OffsetNanoseconds]] to ParseTimeZoneOffsetString(_identifier_). 1. Else, - 1. Assert: ! CanonicalizeTimeZoneName(_identifier_) is _identifier_. + 1. Assert: GetAvailableNamedTimeZoneIdentifier(_identifier_).[[PrimaryIdentifier]] is _identifier_. 1. Set _object_.[[Identifier]] to _identifier_. 1. Set _object_.[[OffsetNanoseconds]] to ~empty~. 1. Return _object_. @@ -421,7 +341,32 @@

Implementations are free to store either or both representations.

- + + + +

+ GetAvailableNamedTimeZoneIdentifier ( + _timeZoneIdentifier_: a String, + ): either a Time Zone Identifier Record or ~empty~ +

+
+
description
+
+ If _timeZoneIdentifier_ is an available named time zone identifier, then it returns one of the records in the List returned by AvailableNamedTimeZoneIdentifiers. + Otherwise, ~empty~ will be returned. +
+
+ + 1. For each element _record_ of AvailableNamedTimeZoneIdentifiers(), do + 1. If _record_.[[Identifier]] is an ASCII-case-insensitive match for _timeZoneIdentifier_, return _record_. + 1. Return ~empty~. + + + For any _timeZoneIdentifier_, or any value that is an ASCII-case-insensitive match for it, the resulting Time Zone Identifier Record must contain the same field values for the lifetime of the surrounding agent. + Furthermore, time zone identifiers must not dynamically change from primary to non-primary during the lifetime of the surrounding agent, meaning that if _timeZoneIdentifier_ is an ASCII-case-insensitive match for the [[PrimaryIdentifier]] field of the result of a previous call to GetAvailableNamedTimeZoneIdentifier, then GetAvailableNamedTimeZoneIdentifier(_timeZoneIdentifier_) must return a record where [[Identifier]] is [[PrimaryIdentifier]]. + Due to the complexity of supporting these requirements, it is recommended that the result of AvailableNamedTimeZoneIdentifiers (and therefore GetAvailableNamedTimeZoneIdentifier) remains the same for the lifetime of the surrounding agent. + +

@@ -622,8 +567,9 @@

1. If _parseResult_.[[Name]] is not *undefined*, then 1. Let _name_ be _parseResult_.[[Name]]. 1. If IsTimeZoneOffsetString(_name_) is *true*, return CanonicalizeTimeZoneOffsetString(_name_). - 1. If IsAvailableTimeZoneName(_name_) is *false*, throw a *RangeError* exception. - 1. Return ! CanonicalizeTimeZoneName(_name_). + 1. Let _timeZoneIdentifierRecord_ be GetAvailableNamedTimeZoneIdentifier(_name_). + 1. If _timeZoneIdentifierRecord_ is ~empty~, throw a *RangeError* exception. + 1. Return _timeZoneIdentifierRecord_.[[PrimaryIdentifier]]. 1. If _parseResult_.[[Z]] is *true*, return *"UTC"*. 1. Return CanonicalizeTimeZoneOffsetString(_parseResult_.[[OffsetString]]). @@ -641,7 +587,7 @@

1. If _timeZoneSlotValue_ is a String, then - 1. Assert: Either IsTimeZoneOffsetString(_timeZoneSlotValue_) or IsAvailableTimeZoneName(_timeZoneSlotValue_) is *true*. + 1. Assert: Either IsTimeZoneOffsetString(_timeZoneSlotValue_) is *true*, or GetAvailableNamedTimeZoneIdentifier(_timeZoneSlotValue_) is not ~empty~. 1. Return _timeZoneSlotValue_. 1. Let _identifier_ be ? Get(_timeZoneSlotValue_, *"id"*). 1. If _identifier_ is not a String, throw a *TypeError* exception.