Skip to content

Commit

Permalink
Clarify which time zones must be supported in a non-402 implementation
Browse files Browse the repository at this point in the history
The abstract operations dealing with the system time zone and the time
zone names were part of 402, but here they need to move into 262, without
obligating non-402 implementations to offer the full list of time zone
names.

Closes: #1292
  • Loading branch information
ptomato committed Jan 22, 2021
1 parent 185232f commit e0aed78
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 23 deletions.
4 changes: 2 additions & 2 deletions spec/abstractops.html
Original file line number Diff line number Diff line change
Expand Up @@ -1415,8 +1415,8 @@ <h1>ParseTemporalTimeZoneString ( _isoString_ )</h1>
1. Let _offsetNanoseconds_ be _sign_ × (((_hours_ × 60 + _minutes_) × 60 + _seconds_) × 10<sup>9</sup> + _nanoseconds_).
1. Let _offsetString_ be ! FormatTimeZoneOffsetString(_offsetNanoseconds_).
1. If _name_ is not *undefined*, then
1. Assert: ! IsValidTimeZoneName(_name_) is *true*.
1. Set _name_ to ! CanonicalizeTimeZoneName(_name_).
1. Assert: ! HostIsValidTimeZoneName(_name_) is *true*.
1. Set _name_ to ! HostCanonicalizeTimeZoneName(_name_).
1. Return the new Record: {
[[Z]]: *undefined*,
[[OffsetString]]: _offsetString_,
Expand Down
30 changes: 15 additions & 15 deletions spec/biblio.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"https://tc39.es/ecma262/": [
{
"type": "op",
"aoid": "CodePointsToString",
"id": "sec-codepointstostring"
},
{
"type": "op",
"aoid": "NumberToBigInt",
Expand All @@ -15,11 +20,21 @@
"aoid": "RequireInternalSlot",
"id": "sec-requireinternalslot"
},
{
"type": "op",
"aoid": "StringToCodePoints",
"id": "sec-stringtocodepoints"
},
{
"type": "op",
"aoid": "ToBigInt",
"id": "sec-tobigint"
},
{
"type": "clause",
"number": "D.1",
"id": "sec-host-hooks-summary"
},
{
"type": "term",
"term": "%Date.now%",
Expand All @@ -32,11 +47,6 @@
}
],
"https://tc39.es/ecma402/": [
{
"type": "op",
"aoid": "IsValidTimeZoneName",
"id": "sec-isvalidtimezonename"
},
{
"type": "op",
"aoid": "BasicFormatMatcher",
Expand All @@ -52,16 +62,6 @@
"aoid": "CanonicalizeLocaleList",
"id": "sec-canonicalizelocalelist"
},
{
"type": "op",
"aoid": "CanonicalizeTimeZoneName",
"id": "sec-canonicalizetimezonename"
},
{
"type": "op",
"aoid": "DefaultTimeZone",
"id": "sec-defaulttimezone"
},
{
"type": "op",
"aoid": "FormatNumeric",
Expand Down
68 changes: 66 additions & 2 deletions spec/intl.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,70 @@ <h1>Amendments to the ECMAScript® 2021 Internationalization API Specification</
</p>
</emu-note>

<emu-clause id="sup-time-zone-names">
<h1><a href="https://tc39.es/ecma402/#sec-time-zone-names">Time Zone Names</a></h1>

<ins class="block">
<p>
<emu-xref href="#sec-time-zone-names"></emu-xref> defines a set of host-defined abstract operations concerning the names of supported time zones.
This section introduces additional requirements on how ECMAScript hosts that are conforming implementations of the ECMAScript 2021 Internationalization API Specification may implement these operations.
</p>
</ins>

<p>
The ECMAScript 2021 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.
</p>

<p>
All registered Zone and Link names are allowed. <ins>Conforming</ins> implementations must recognize all 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.
</p>

<emu-clause id="sec-intl-hostisvalidtimezonename">
<h1><a href="https://tc39.es/ecma402/#sec-isvalidtimezonename"><ins>Host</ins>IsValidTimeZoneName</a> ( _timeZone_ )</h1>

<p>
<del>The</del> <ins>Host</ins>IsValidTimeZoneName <ins>is a host-defined</ins> abstract operation <ins>which</ins> verifies that the _timeZone_ argument (which must be a String value) represents a valid Zone or Link name of the IANA Time Zone Database.
<ins>A conforming implementation must implement the abstract operation as follows:</ins>
</p>
<p>
The abstract operation returns true if _timeZone_, converted to upper case as described in <emu-xref href="#sec-case-sensitivity-and-case-mapping"></emu-xref>, is equal to one of the Zone or Link names of the IANA Time Zone Database, converted to upper case as described in <emu-xref href="#sec-case-sensitivity-and-case-mapping"></emu-xref>. It returns false otherwise.
</p>
</emu-clause>

<emu-clause id="sec-intl-hostcanonicalizetimezonename">
<h1><a href="https://tc39.es/ecma402/#sec-canonicalizetimezonename"><ins>Host</ins>CanonicalizeTimeZoneName</a> <ins>( _timeZone_ )</ins></h1>

<p>
<del>The</del> <ins>Host</ins>CanonicalizeTimeZoneName <ins>is a host-defined</ins> abstract operation <ins>which</ins> returns the canonical and case-regularized form of the _timeZone_ argument (which must be a String value that is a valid time zone name as verified by the <ins>Host</ins>IsValidTimeZoneName abstract operation).
<del>The following steps are taken:</del>
<ins>A conforming implementation must implement the abstract operation as follows:</ins>
</p>

<emu-alg>
1. <ins>Assert: Type(_timeZone_) is String.</ins>
1. <ins>Assert: ! HostIsValidTimeZoneName(_timeZone_) is *true*.</ins>
1. Let _ianaTimeZone_ be the Zone or Link name of the IANA Time Zone Database such that _timeZone_, converted to upper case as described in <emu-xref href="#sec-case-sensitivity-and-case-mapping"></emu-xref>, is equal to _ianaTimeZone_, converted to upper case as described in <emu-xref href="#sec-case-sensitivity-and-case-mapping"></emu-xref>.
1. If _ianaTimeZone_ is a Link name, let _ianaTimeZone_ be the corresponding Zone name as specified in the *"backward"* file of the IANA Time Zone Database.
1. If _ianaTimeZone_ is *"Etc/UTC"* or *"Etc/GMT"*, return *"UTC"*.
1. Return _ianaTimeZone_.
</emu-alg>

<p>
The Intl.DateTimeFormat constructor allows this time zone name; if the time zone is not specified, the host environment's current time zone is used. Implementations shall support UTC and the <del>host environment's current</del> time zone <ins>returned from DefaultTimeZone</ins> (if different from UTC) in formatting.
</p>
</emu-clause>

<del class="block">
<emu-clause id="sec-intl-defaulttimezone">
<h1><a href="https://tc39.es/ecma402/#sec-defaulttimezone">DefaultTimeZone</a> ( )</h1>

<p>
The DefaultTimeZone abstract operation returns a String value representing the valid (<emu-xref href="#sec-hostisvalidtimezonename"></emu-xref>) and canonicalized (<emu-xref href="#sec-hostcanonicalizetimezonename"></emu-xref>) time zone name for the host environment's current time zone.
</p>
</emu-clause>
</del>
</emu-clause>

<emu-clause id="sec-datetimeformat-abstracts">
<h1><a href="https://tc39.es/ecma402/#sec-datetimeformat-abstracts">Abstract Operations For DateTimeFormat Objects</a></h1>

Expand Down Expand Up @@ -133,9 +197,9 @@ <h1>InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ )</h1>
1. Let _timeZone_ be DefaultTimeZone().
1. Else,
1. Let _timeZone_ be ? ToString(_timeZone_).
1. If the result of IsValidTimeZoneName(_timeZone_) is *false*, then
1. If <del>the result of</del> <ins>! Host</ins>IsValidTimeZoneName(_timeZone_) is *false*, then
1. Throw a *RangeError* exception.
1. Let _timeZone_ be CanonicalizeTimeZoneName(_timeZone_).
1. Let _timeZone_ be <ins>! Host</ins>CanonicalizeTimeZoneName(_timeZone_).
1. Set _dateTimeFormat_.[[TimeZone]] to _timeZone_.
1. Let _opt_ be a new Record.
1. For each row of <emu-xref href="#table-datetimeformat-components"></emu-xref>, except the header row, in table order, do
Expand Down
99 changes: 95 additions & 4 deletions spec/timezone.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,97 @@
<h1>Temporal.TimeZone Objects</h1>
<p>A Temporal.TimeZone object is an immutable Object referencing a time zone.</p>

<emu-clause id="sec-time-zone-names">
<h1>Time Zone Names</h1>

<p>
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 of DefaultTimeZone is different from *"UTC"*, 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.
</p>
<p>
<emu-xref href="#sec-temporal-timezone-constructor">The `Temporal.TimeZone` constructor</emu-xref>, 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.
</p>
<p>
Implementations are encouraged to support the Zone and Link names of the IANA Time Zone Database, and to use the best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations.
</p>
<p>
An ECMAScript implementation that includes the ECMA-402 Internationalization API has additional requirements for the built-in time zones that must be supported, as specified in the ECMA-402 specification.
</p>

<emu-note type="editor">
<p>These host hooks need to be added to ES2021 <emu-xref href="#sec-host-hooks-summary"></emu-xref> when merged in.</p>
</emu-note>

<emu-clause id="sec-hostisvalidtimezonename" aoid="HostIsValidTimeZoneName">
<h1>HostIsValidTimeZoneName ( _timeZone_ )</h1>

<p>
HostIsValidTimeZoneName is a host-defined abstract operation that takes argument _timeZone_ (a String value).
It verifies that _timeZone_ represents a valid built-in time zone.
</p>
<p>
The implementation of HostIsValidTimeZoneName must conform to the following requirements:
</p>
<ul>
<li>It must always complete normally (i.e., not return an abrupt completion.)</li>
<li>It must always return either *true* or *false*.</li>
</ul>
<p>
The implementation of HostIsValidTimeZoneName should return *true* if _timeZone_, converted to upper case, is equal to one of the built-in time zone names, converted to upper case.
It should return *false* otherwise.
</p>
<p>The minimum implementation of HostIsValidTimeZoneName, supporting only the *"UTC"* time zone, performs the following steps when called:
</p>

<emu-alg>
1. Assert: Type(_timeZone_) is String.
1. Let _tzText_ be ! StringToCodePoints(_timeZone_).
1. Let _tzUpperText_ be the result of toUppercase(_tzText_), according to the Unicode Default Case Conversion algorithm.
1. Let _tzUpper_ be ! CodePointsToString(_tzUpperText_).
1. If _tzUpper_ and *"UTC"* are the same sequence of code points, return *true*.
1. Return *false*.
</emu-alg>
</emu-clause>

<emu-clause id="sec-hostcanonicalizetimezonename" aoid="HostCanonicalizeTimeZoneName">
<h1>HostCanonicalizeTimeZoneName ( _timeZone_ )</h1>

<p>
HostCanonicalizeTimeZoneName is a host-defined abstract operation that takes argument _timeZone_ (a String value).
It returns the canonical and case-regularized form of the _timeZone_ argument.
</p>
<p>
The _timeZone_ parameter must be a valid time zone name according to HostIsValidTimeZoneName.
</p>
<p>
The implementation of HostCanonicalizeTimeZoneName must conform to the following requirements:
</p>
<ul>
<li>It must always complete normally (i.e., not return an abrupt completion.)</li>
<li>It must always return a String value.</li>
</ul>
<p>The minimum implementation of HostCanonicalizeTimeZoneName, supporting only the *"UTC"* time zone, performs the following steps when called:
</p>

<emu-alg>
1. Assert: Type(_timeZone_) is String.
1. Assert: ! HostIsValidTimeZoneName(_timeZone_) is *true*.
1. Return *"UTC"*.
</emu-alg>
</emu-clause>

<emu-clause id="sec-defaulttimezone" aoid="DefaultTimeZone">
<h1>DefaultTimeZone ( )</h1>

<p>
The DefaultTimeZone abstract operation returns a String value representing the valid (<emu-xref href="#sec-hostisvalidtimezonename"></emu-xref>) and canonicalized (<emu-xref href="#sec-hostcanonicalizetimezonename"></emu-xref>) time zone name for the host environment's current time zone.
</p>
</emu-clause>
</emu-clause>

<emu-clause id="sec-temporal-timezone-constructor">
<h1>The Temporal.TimeZone Constructor</h1>
<p>
Expand All @@ -30,9 +121,9 @@ <h1>Temporal.TimeZone ( _identifier_ )</h1>
1. Let _offsetNanoseconds_ be ? ParseTimeZoneOffsetString(_identifier_).
1. Let _canonical_ be ? FormatTimeZoneOffsetString(_offsetNanoseconds_).
1. Else,
1. If ! IsValidTimeZoneName(_id_) is *false*, then
1. If ! HostIsValidTimeZoneName(_id_) is *false*, then
1. Throw a *RangeError* exception.
1. Let _canonical_ be ! CanonicalizeTimeZoneName(_identifier_).
1. Let _canonical_ be ! HostCanonicalizeTimeZoneName(_identifier_).
1. Return ? CreateTemporalTimeZone(_canonical_, NewTarget).
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -364,7 +455,7 @@ <h1>Abstract operations</h1>
<emu-clause id="sec-temporal-createtemporaltimezonefromstatic" aoid="CreateTemporalTimeZoneFromStatic">
<h1>CreateTemporalTimeZoneFromStatic ( _constructor_, _identifier_ )</h1>
<emu-alg>
1. Assert: ! IsValidTimeZoneName(_identifier_) is *true*.
1. Assert: ! HostIsValidTimeZoneName(_identifier_) is *true*.
1. If ! IsConstructor(_constructor_) is *false*, throw a *TypeError* exception.
1. Let _result_ be ? Construct(_constructor_, « _identifier_ »).
1. Perform ? RequireInternalSlot(_result_, [[InitializedTemporalTimeZone]]).
Expand All @@ -385,7 +476,7 @@ <h1>ParseTemporalTimeZone ( _string_ )</h1>
<emu-clause id="sec-temporal-createtemporaltimezone" aoid="CreateTemporalTimeZone">
<h1>CreateTemporalTimeZone ( _identifier_ [ , _newTarget_ ] )</h1>
<emu-alg>
1. Assert: ! CanonicalizeTimeZoneName(_identifier_) is _identifier_.
1. Assert: ! HostCanonicalizeTimeZoneName(_identifier_) is _identifier_.
1. If _newTarget_ is not given, set it to %Temporal.TimeZone%.
1. Let _object_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%Temporal.TimeZone.prototype%"*, « [[InitializedTemporalTimeZone]], [[Identifier]], [[OffsetNanoseconds]] »).
1. Set _object_.[[Identifier]] to _identifier_.
Expand Down

0 comments on commit e0aed78

Please sign in to comment.