-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Normative: Allow UTC offset time zones #788
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,9 +94,18 @@ <h1> | |
1. Set _timeZone_ to DefaultTimeZone(). | ||
1. Else, | ||
1. Set _timeZone_ to ? ToString(_timeZone_). | ||
1. If the result of IsValidTimeZoneName(_timeZone_) is *false*, then | ||
1. Throw a *RangeError* exception. | ||
1. If IsTimeZoneOffsetString(_timeZone_) is *true*, then | ||
1. Let _parseResult_ be ParseText(StringToCodePoints(_timeZone_), |UTCOffset|). | ||
1. Assert: _parseResult_ is a Parse Node. | ||
1. If _parseResult_ contains more than one |MinuteSecond| Parse Node, throw a *RangeError* exception. | ||
1. Let _offsetNanoseconds_ be ParseTimeZoneOffsetString(_timeZone_). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a new CanonicalizeTimeZoneOffsetString AO in Temporal. Should this be brought into 402 to replace this line and the one below it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried to keep changes minimal here, but intend to make use of CanonicalizeTimeZoneOffsetString once it lands in ECMA-262. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not understand why not just change the definition of HourSubcomponents in ECMA262 instead
why not change it to just
? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only place reference to it is UTCOffset and the only places refence to UTCOffset are which are exactly the two places we need to change and both places are only used by place dealing with system timezone. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @FrankYFTang An ECMA-262 grammar cannot be changed from an ECMA-402 pull request. But all of this will be simplified by/in response to Temporal, as demonstrated in #788 (comment) . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing I do not understand is why do we have this PR for ECMA402 instead of just let Temporal to change both ECMA262 and 402. What is the urgent need for that to happen before Temporal reach stage 4? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK, the main reason is that offset time zones are currently supported in (pre-Temporal) ECMA-262. My assumption is that all ECMA-262 features should be supported when ECMA-402 is also implemented. Also, do we know yet whether ICU and/or CLDR changes will be needed to enable formatting of offset time zones? If no, that's great news. If yes, then where do changes need to be made? |
||
1. Let _offsetMinutes_ be _offsetNanoseconds_ / (6 × 10<sup>10</sup>). | ||
1. Assert: _offsetMinutes_ is an integer. | ||
1. Set _timeZone_ to FormatOffsetTimeZoneIdentifier(_offsetMinutes_). | ||
justingrant marked this conversation as resolved.
Show resolved
Hide resolved
|
||
1. Else if IsValidTimeZoneName(_timeZone_) is *true*, then | ||
1. Set _timeZone_ to CanonicalizeTimeZoneName(_timeZone_). | ||
1. Else, | ||
1. Throw a *RangeError* exception. | ||
1. Set _dateTimeFormat_.[[TimeZone]] to _timeZone_. | ||
1. Let _formatOptions_ be a new Record. | ||
1. Set _formatOptions_.[[hourCycle]] to _hc_. | ||
|
@@ -164,6 +173,27 @@ <h1> | |
1. Return _dateTimeFormat_. | ||
</emu-alg> | ||
</emu-clause> | ||
|
||
<emu-clause id="sec-formatoffsettimezoneidentifier" type="abstract operation"> | ||
<h1> | ||
FormatOffsetTimeZoneIdentifier ( | ||
_offsetMinutes_: an integer, | ||
): a String | ||
</h1> | ||
<dl class="header"> | ||
<dt>description</dt> | ||
<dd> | ||
It formats a UTC offset, in minutes, into a UTC offset string formatted like ±HH:MM. | ||
</dd> | ||
</dl> | ||
<emu-alg> | ||
1. If _offsetMinutes_ ≥ 0, let _sign_ be the code unit 0x002B (PLUS SIGN); otherwise, let _sign_ be the code unit 0x002D (HYPHEN-MINUS). | ||
1. Let _absoluteMinutes_ be abs(_offsetMinutes_). | ||
1. Let _hours_ be floor(_absoluteMinutes_ / 60). | ||
1. Let _minutes_ be _absoluteMinutes_ modulo 60. | ||
1. Return the string-concatenation of _sign_, ToZeroPaddedDecimalString(_hours_, 2), the code unit 0x003A (COLON), and ToZeroPaddedDecimalString(_minutes_, 2). | ||
</emu-alg> | ||
</emu-clause> | ||
</emu-clause> | ||
|
||
<emu-clause id="sec-properties-of-intl-datetimeformat-constructor"> | ||
|
@@ -679,7 +709,7 @@ <h1>Properties of Intl.DateTimeFormat Instances</h1> | |
<li>[[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.</li> | ||
<li>[[Calendar]] is a String value representing the <a href="https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier">Unicode Calendar Identifier</a> used for formatting.</li> | ||
<li>[[NumberingSystem]] is a String value representing the <a href="https://unicode.org/reports/tr35/#UnicodeNumberSystemIdentifier">Unicode Number System Identifier</a> used for formatting.</li> | ||
<li>[[TimeZone]] is a String value that is a time zone identifier from the IANA Time Zone Database used for formatting.</li> | ||
<li>[[TimeZone]] is a String value used for formatting that is either a time zone identifier from the IANA Time Zone Database or a UTC offset in ISO 8601 extended format.</li> | ||
<li>[[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[TimeZoneName]] are each either *undefined*, indicating that the component is not used for formatting, or one of the String values given in <emu-xref href="#table-datetimeformat-components"></emu-xref>, indicating how the component should be presented in the formatted output.</li> | ||
<li>[[FractionalSecondDigits]] is either *undefined* or a positive, non-zero integer Number value indicating the fraction digits to be used for fractional seconds. Numbers will be rounded or padded with trailing zeroes if necessary.</li> | ||
<li>[[HourCycle]] is a String value indicating whether the 12-hour format (*"h11"*, *"h12"*) or the 24-hour format (*"h23"*, *"h24"*) should be used. *"h11"* and *"h23"* start with hour 0 and go up to 11 and 23 respectively. *"h12"* and *"h24"* start with hour 1 and go up to 12 and 24. [[HourCycle]] is only used when [[Hour]] is not *undefined*.</li> | ||
|
@@ -1150,7 +1180,11 @@ <h1> | |
</dl> | ||
|
||
<emu-alg> | ||
1. Let _offsetNs_ be GetNamedTimeZoneOffsetNanoseconds(_timeZoneIdentifier_, _epochNs_). | ||
1. If IsTimeZoneOffsetString(_timeZoneIdentifier_) is *true*, then | ||
1. Let _offsetNs_ be ParseTimeZoneOffsetString(_timeZoneIdentifier_). | ||
1. Else, | ||
1. Assert: IsValidTimeZoneName(_timeZoneIdentifier_) is *true*. | ||
1. Let _offsetNs_ be GetNamedTimeZoneOffsetNanoseconds(_timeZoneIdentifier_, _epochNs_). | ||
1. Let _tz_ be ℝ(_epochNs_) + _offsetNs_. | ||
1. If _calendar_ is *"gregory"*, then | ||
1. Return a record with fields calculated from _tz_ according to <emu-xref href="#table-datetimeformat-tolocaltime-record"></emu-xref>. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure how does "contains more than one |MinuteSecond| Parse Node" work here.
How is the "contains" operation defined for Parse Node? I cannot find a concrete definition.
Look at the UTCOffset grammar in https://tc39.es/ecma262/#sec-time-zone-offset-string-format
So if the concept of "contains" is shallow, then it would be impossible for UTCOffset to contain any MinuteSecond.
since 1 or 2 MinuteSecond could be contain inside the HourSubcomponents that contained by UTCOffset. However, the require a "deep containment" interpretation and I am not sure that is what ECMA262 specify. (since I cannot find a clear definition of what "contains" mean for Parse Node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@FrankYFTang This use of "contains" is prose of the sort that is also currently in Temporal ParseTimeZoneIdentifier—as suggested by the lack of automatic hyperlinking, there is no concrete definition. However, as I thought would be clear from context in both documents, it is intended to be understood as entailing deep inspection of the tree of Parse Nodes. Can you suggest a change here that would make that more clear?
I could define a precise syntax-directed operation, but really don't want to do that because it would apply cross-document to the ECMA-262 |UTCOffset| nonterminal that will be replaced by Temporal |TimeZoneUTCOffsetName| (creating a situation where this part of ECMA-402 would be incoherent until fixed).
It's also worth noting that this explicit check for multiple |MinuteSecond| Parse Nodes will itself be removed when Temporal lands, along with many of the other steps here that are subsumed by ParseTimeZoneIdentifier: