iamkun / dayjs

⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API
https://day.js.org
MIT License
46.55k stars 2.28k forks source link

typo in zone name Europe/Kyiv ? #2059

Open tijujohn83 opened 1 year ago

tijujohn83 commented 1 year ago

'Europe/Kyiv' is not recognized but 'Europe/Kiev' is

example: following throws error as dayjs('2018-01-02T00:00:00Z').tz('Europe/Kyiv')

image

Information

boyanstanchev commented 1 year ago

dayjs is using the Intl API, where the timezone is listed as 'Europe/Kiev'

You can check by yourself Intl.supportedValuesOf('timeZone')

chrome_lJULdLM0zX

tukusejssirs commented 1 year ago

Just a note: Kiev is official English name of the city (derived from the Russian spelling), while Kyiv is transliteration of its Ukrainian name. Thus in English, Kyiv spelling is incorrect, although it is used by many people.

I think this issue should be closed, as until it is officially changed (by international English community and specifically by Intl API; see also KyivNotKiev campaign), there is not much dayjs can do.

/cc @iamkun

justingrant commented 1 year ago

ECMAScript libraries that accept time zone identifier string inputs generally accept both Europe/Kiev and Europe/Kyiv. This follows the behavior ofIntl.DateTimeFormat, as well as the coming-soon Temporal.TimeZone and Temporal.ZonedDateTime types. (Full disclosure: I'm part of the team that designed the Temporal API, and I did a lot of work on the time-zone-related parts of it.)

If you want to know more about why both spellings should be accepted, below is background info.

Time zone identifiers in ECMAScript are based on the IANA Time Zone Database, or "TZDB". The TZDB has a backwards compatibility mechanism where multiple names (called "Links" in TZDB) can map to the same canonical time zone (called "Zone" in TZDB). So it's surprising that an Intl-based library would not accept all aliases for a time zone.

Here's some code showing that Intl.DateTimeFormat accepts both.

// Chrome, Safari
new Intl.DateTimeFormat('en', { timeZone: 'Europe/Kiev' }).resolvedOptions().timeZone;
// => 'Europe/Kiev'
new Intl.DateTimeFormat('en', { timeZone: 'Europe/Kyiv' }).resolvedOptions().timeZone;
// => 'Europe/Kiev'

// Firefox
new Intl.DateTimeFormat('en', { timeZone: 'Europe/Kiev' }).resolvedOptions().timeZone;
// => 'Europe/Kyiv'
new Intl.DateTimeFormat('en', { timeZone: 'Europe/Kyiv' }).resolvedOptions().timeZone;
// => 'Europe/Kyiv'

You'll notice that Firefox behavior differs from Chrome and Safari. This is because Firefox is actually following the TZDB. Here's an excerpt from the latest TZDB showing that Europe/Kyiv is a Zone (it's the canonical identifier) while Europe/Kiev is a Link (not canonical). You can see the latest TZDB Zones and Links here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.

image

The reason why Chrome and Safari return Europe/Kiev as canonical is because they rely on an internationalization library called ICU4C, which in turn gets its list of time zone identifiers (including which is canonical) from a data store called CLDR. It's the policy of ICU and CLDR to never update the canonical alias of a time zone once it's ever been published. This behavior has gradually led to a stale set of canonical identifiers in Chrome and Safari. It's not just Europe/Kiev, but also Asia/Calcutta (should be Asia/Kolkata), Asia/Saigon (should be Asia/Ho_Chi_Minh), and 10 more outdated canonical identifiers.

Firefox avoids this problem by determining canonical IDs directly from TZDB. Of course, that's not a panacea either because TZDB has lately been aggressively merging unrelated time zones (like Atlantic/Reykjavik + Africa/Abidjan, or Europe/Oslo + Europe/Berlin) and Firefox wisely backs these out using build options in the MAKEFILE of TZDB.

If you think this divergence between browsers is a bad idea, well I do too! I recently started a TC39 proposal to try to help fix it. Feedback on this proposal is always welcome.

This is probably much more information than you wanted to know about time zone identifiers, but if you're reading a bug report on dayjs then you might be a time zone nerd like me. :-)