-
Notifications
You must be signed in to change notification settings - Fork 158
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: Address time zone and calendar case sensitivity #2395
Conversation
cc @anba |
Codecov Report
@@ Coverage Diff @@
## main #2395 +/- ##
=======================================
Coverage 94.75% 94.76%
=======================================
Files 20 20
Lines 10991 11003 +12
Branches 1962 1963 +1
=======================================
+ Hits 10415 10427 +12
Misses 531 531
Partials 45 45
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
spec/abstractops.html
Outdated
@@ -1041,6 +1041,8 @@ <h1>ISO 8601 grammar</h1> | |||
TimeZoneIANANameComponent `/` TimeZoneIANANameTail | |||
|
|||
TimeZoneIANALegacyName : | |||
> An ASCII-case-insensitive match for one of the following: |
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 don't think this is valid notation, cf. https://tc39.es/ecma262/multipage/notational-conventions.html#sec-notational-conventions . There are probably many alternative approaches, but the one that comes to mind for me is providing a broad general definition of |TimeZoneIANALegacyName| (e.g., TimeZoneIANALegacyName ::: TimeZoneIANANameTail[+Legacy]
where the Legacy parameter is passed down ultimately to |TZChar| for [+Legacy] DecimalDigit
and [+Legacy] `+`
expansions), using early errors or a [> but only …]
prose assertion to restrict it to case-insensitive matches of this finite list, and adding an ambiguity-avoiding "but not TimeZoneIANANameTail" restriction in the reference to it from |TimeZoneIANAName|.
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.
Ugh, I was hoping that the prose description given here would be a sufficiently unambiguous description of what this production can match. This suggestion makes the grammar less easy to understand in my opinion... but I've tacked it on in an extra commit, see what you think of it. Having seen both, I'd personally prefer to leave it as it was.
I used a prose assertion instead of an early error here to restrict it to the specific legacy names; I find the notation less readable, but on the other hand more readable that it's right there in |TimeZoneLegacyIANAName| rather than at the end where an early error would be. It doesn't seem to me that the "but not TimeZoneIANANameTail" is necessary, because if |TimeZoneLegacyIANAName| is restricted to a finite list, it can't be ambiguous with TimeZoneIANANameTail[~Legacy].
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.
@gibson042 Let me know what you think of this solution. I'd rather keep it the way it was, but if you think this is an improvement then I'm fine with that too.
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.
According to ECMA-262, "a few nonterminal symbols are described by a descriptive phrase in sans-serif type in cases where it would be impractical to list all the alternatives" — I think this sufficiently describes the original prose description I had; I find the current solution in this PR impractical. I'll propose that we go ahead and merge this with the original prose description unless I hear any objections soon, since Frank is waiting on it.
spec/abstractops.html
Outdated
@@ -1041,6 +1041,8 @@ <h1>ISO 8601 grammar</h1> | |||
TimeZoneIANANameComponent `/` TimeZoneIANANameTail | |||
|
|||
TimeZoneIANALegacyName : | |||
> An ASCII-case-insensitive match for one of the following: | |||
`Etc/GMT` ASCIISign UnpaddedHour |
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.
If the same nonterminal is going to include legacy names and Etc/GMT±<h> names, I think it should be named "Special" rather than "Legacy".
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.
Re-reading Timezone identifiers, Etc/GMT± is actually also a legacy name, so I think this change makes it actually more correct.
This achieved consensus at the September 2022 TC39 meeting. It's covered by test262 tests. |
While #2395 is still pending the resolution of the case-insensitive grammar question, its tests are expected to fail.
While #2395 is still pending the resolution of the case-insensitive grammar question, its tests are expected to fail.
While #2395 is still pending the resolution of the case-insensitive grammar question, its tests are expected to fail.
a91e528
to
1f53d41
Compare
What is blocking this to be merged |
1f53d41
to
8156502
Compare
Previously, there was a discrepancy in the case-sensitivity of IANA legacy time zone names that were accepted by new Temporal.TimeZone() vs. Temporal.TimeZone.from(). This clarifies definitively that the following are all valid: new Temporal.TimeZone('eTc/gMt+1') Temporal.TimeZone.from('eTc/gMt+1') Temporal.TimeZone.from('2022-08-30T14:18[eTc/gMt+1]')
For consistency with ECMA-402, where calendar names are case-insensitive, Temporal should also accept calendar names case-insensitively. This clarifies definitively that the following are all valid: new Temporal.Calendar('jApAnEsE') Temporal.Calendar.from('jApAnEsE') Temporal.Calendar.from('2022-08-30[u-ca=jApAnEsE]') This is in line with the already-existing new Date().toLocaleString('en', { calendar: 'jApAnEsE' }) new Date().toLocaleString('en-u-ca-jApAnEsE')
In case the prose description is not sufficiently correct notation, here's an alternative notation suggested by Richard, where time zone characters get a "Legacy" parameter which includes the otherwise illegal + and digit characters, and |TimeZoneIANALegacyName| gets an explicit prose assertion that ensures it can only match case-insensitive matches for the specific legacy names.
With this change, the corresponding test262 tests will no longer fail.
8156502
to
b003411
Compare
This is implied by the canonical form of a calendar type being lowercase, but not explicit until now.
This moves the definitions of ASCII-uppercase, ASCII-lowercase, and ASCII- case-insensitive match into ECMA-262 and deletes them from ECMA-402. It also generalizes the definitions of ASCII-uppercase and ASCII-lowercase to cover sequences of code points as well as strings. This allows a simplification in the TimeZoneIANALegacyName production. (Note, the unnecessary parentheses are because grammarkdown seems to choke on the version without them)
I would still rather we'd go with the much simpler prose description of IANATimeZoneLegacyName, but I'm fine to let that be an editorial matter for Stage 4, especially since Frank is waiting for this PR to be merged. |
Makes all of the following work:
Closes: #2326