Open chrisveness opened 2 years ago
new Intl.DateTimeFormat('en-US', {timeZone: 'asia/kathmandu'}).resolvedOptions().timeZone
The underlying implementation here parses the timezone by asking the Intl.DateTimeFormat API surface to "resolve" the TimeZone into a canonical identifier.
Hmm... so the Intl.DateTimeFormat
API has the ‘wrong’ canonical identifier? (In that it doesn't match the Iana Time Zone Database).
That's tricky!
I wouldn't even know where to go to report that...
I think this is the same issue as Asia/Kolkata in V8: https://bugs.chromium.org/p/chromium/issues/detail?id=580195
Thank you Philip – I've added a note about Asia/Kathmandu to that Chromium bug.
The root cause issue is this one: https://unicode-org.atlassian.net/browse/CLDR-9892.
Some context: the authoritative source of time zone information is the IANA Time Zone Database, sometimes called TZDB.
Because TZDB is based on city names, and sometimes city names change over time, TZDB maintains a synonyms list where multiple names correspond to the same underlying time zone. For example, Asia/Calcutta
and Asia/Kolkata
point to the same time zone data. One of these synonyms is declared to be the "canonical" one. The others are supposed to redirect to that one.
But the time zone database used by JS engines is maintained by the CLDR group that's part of Unicode. (CLDR also maintains calendar info and other globalization data used by JS.)
Browsers in turn take the data produced by CLDR and use it to power various globalization-related features, including all features that use time zones. CLDR generally adopts TZDB updates, but it seems that CLDR tries to maintain consistency of canonical synonyms, in order to avoid breaking changes. There are a billion people living in Asia/Kolkata (which JS engines canonicalize to Asia/Calcutta). If these canonical resolutions were changed, it'd likely cause problems for a decent percentage of those billion people.
I'm not claiming this is the correct decision, only trying to explain my understanding of why CLDR and/or JS engines have chosen not not update canonical time zone resolutions for renamed cities.
@sffc please correct me if I got any of the facts wrong above! 🙏
The reason I think this is a Chromium bug is that only Chrome/Chromium interprets the CLDR data to mean that Asia/Kolkata should be canonicalized to Asia/Calcutta. Other browsers (correctly, IMO) canonicalize Asia/Calcutta to Asia/Kolkata.
If you use ICU to canonicalize the IANA names, you'll get the CLDR canonical names, which are always the "oldest" name as first defined, even if IANA changes the city name spelling in a future version. If you want to use the IANA canonical forms, don't rely on ICU to do that, I think.
If Temporal requires IANA canonical names instead of CLDR canonical names, that functionality might be able to be added to ICU4C, but we could also provide it in ICU4X.
Does Temporal make this requirement, though? What's wrong with using the CLDR canonical name?
This is independent of Temporal, it shows up when using Intl.DateTimeFormat.p.resolvedOptions()
.
ECMA-402 CanonicalizeTimeZoneName says
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.
According to backward
, Asia/Calcutta
is a Link name, with the target Zone name being Asia/Kolkata
. So, my reading of ECMA-402 is that the IANA canonical name is required, not the CLDR canonical name.
In any case, there is a discrepancy between engines. I just tested and contrary to what I said above, JSC also shares the V8 behaviour; I thought I'd investigated this a couple of years back and V8 was the odd one out, but either that changed or I misremembered.
OK, well if Intl.DateTimeFormat is not being consistent with ECMA-402 spec-required behavior, then that should be tracked as an issue on the ECMA-402 repo.
I see, cool. Looks like it is assigned to @ryzokuken. Seems we need to get alignment on the right path forward.
Per the Iana Timezone Database (https://www.iana.org/time-zones), Kathmandu should be spelt with an 'h' (Asia/Kathmandu).
Temporal will parse the timezone spelt with an 'h', but the resulting id is spelt without an 'h' (Asia/Katmandu).
I think this must be erroneous (and took me some time to debug!).