Skip to content

Commit

Permalink
Bug 1930466 - Part 1: Use zone.tab to guide time zone canonicalisatio…
Browse files Browse the repository at this point in the history
…n. r=dminor

Implement the changes from <tc39/ecma402#877> to reduce
differences in time zone canonicalisation when compared to V8 and JSC (which
both use CLDR time zone data instead of IANA time zone data).

Implementing the `AvailableNamedTimeZoneIdentifiers` spec operation requires to
link time zone identifiers to region codes. When the time zone is listed in the
"zone.tab" file, we can get the region code from "zone.tab". In all other cases
we need to manually map the time zone to a matching region, because CLDR doesn't
have "public" data for this [1]. This is implemented using the new file
"intl/TimeZoneMapping.yaml".

ICU 74 added `ucal_getIanaTimeZoneID` to get the canonical IANA time zone id.
Internally `ucal_getIanaTimeZoneID` first calls `ucal_getCanonicalTimeZoneID`
and then loads a resource bundle to check if there are any time zone ids which
need to be replaced with other ids for compatibility with IANA data. Unfortunately
the resource bundle is not cached, so calling `ucal_getIanaTimeZoneID` instead
of `ucal_getIanaTimeZoneID` adds a considerable performance overhead. To avoid
any performance regressions, we keep our own time zone rewriting code for the
time being.

Using our own code also means we don't have to add a workaround for this CLDR
bug: <https://unicode-org.atlassian.net/browse/CLDR-16439>.

Also remove "Factory" from the list of supported time zone identifiers, because
supporting it was always a bit questionable and latest V8 also doesn't support
it anymore, so we shouldn't run into web-compat issues.

Remove the old generated tests and add "timeZone_links.js" to ensure time zone
links are correctly resolved.

[1] Neither of these two files look like "public" data to me:
- https://github.com/unicode-org/cldr/blob/main/tools/cldr-code/src/main/resources/org/unicode/cldr/util/data/TZID.txt
- https://github.com/unicode-org/cldr/blob/main/tools/cldr-code/src/main/resources/org/unicode/cldr/icu/idList.txt

Differential Revision: https://phabricator.services.mozilla.com/D228584
  • Loading branch information
anba committed Nov 29, 2024
1 parent a05e005 commit 0b0c4f8
Show file tree
Hide file tree
Showing 11 changed files with 442 additions and 601 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ async function verifySpoofed() {
SpecialPowers.Cu.getJSTestingFunctions().setTimeZone("PST8PDT");
is(
Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"America/Los_Angeles",
"Default time zone should have changed"
);

Expand Down Expand Up @@ -116,7 +116,7 @@ add_task(async function test_timezone_exempt() {
SpecialPowers.Cu.getJSTestingFunctions().setTimeZone("PST8PDT");
is(
Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"America/Los_Angeles",
"Default time zone should have changed"
);

Expand All @@ -129,7 +129,7 @@ add_task(async function test_timezone_exempt() {

is(
Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"America/Los_Angeles",
"Content should use default time zone"
);
}
Expand Down Expand Up @@ -172,7 +172,7 @@ add_task(async function test_timezone_exmpt_browser() {
SpecialPowers.Cu.getJSTestingFunctions().setTimeZone("PST8PDT");
is(
Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"America/Los_Angeles",
"Default time zone should have changed"
);

Expand All @@ -182,7 +182,7 @@ add_task(async function test_timezone_exmpt_browser() {

is(
Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"America/Los_Angeles",
"Timezone in chrome should be unaffected by resistFingerprinting"
);

Expand All @@ -196,7 +196,7 @@ add_task(async function test_timezone_exmpt_browser() {

is(
newWindow.Intl.DateTimeFormat("en-US").resolvedOptions().timeZone,
"PST8PDT",
"America/Los_Angeles",
"Timezone in new chrome window should be unaffected by resistFingerprinting"
);

Expand Down
78 changes: 29 additions & 49 deletions js/src/builtin/intl/TimeZoneDataGenerated.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,58 +10,26 @@ namespace timezone {
// Format:
// "ZoneName" // ICU-Name [time zone file]
const char* const ianaZonesTreatedAsLinksByICU[] = {
"Africa/Asmara", // Africa/Asmera [backzone]
"Africa/Timbuktu", // Africa/Bamako [backzone]
"Africa/Asmara", // Africa/Asmera [backward]
"America/Argentina/Buenos_Aires", // America/Buenos_Aires [southamerica]
"America/Argentina/Catamarca", // America/Catamarca [southamerica]
"America/Argentina/ComodRivadavia", // America/Catamarca [backzone]
"America/Argentina/Cordoba", // America/Cordoba [southamerica]
"America/Argentina/Jujuy", // America/Jujuy [southamerica]
"America/Argentina/Mendoza", // America/Mendoza [southamerica]
"America/Atikokan", // America/Coral_Harbour [backzone]
"America/Ensenada", // America/Tijuana [backzone]
"America/Atikokan", // America/Coral_Harbour [backward]
"America/Indiana/Indianapolis", // America/Indianapolis [northamerica]
"America/Kentucky/Louisville", // America/Louisville [northamerica]
"America/Montreal", // America/Toronto [backzone]
"America/Nipigon", // America/Toronto [backzone]
"America/Nuuk", // America/Godthab [europe]
"America/Pangnirtung", // America/Iqaluit [backzone]
"America/Rainy_River", // America/Winnipeg [backzone]
"America/Rosario", // America/Cordoba [backzone]
"America/Thunder_Bay", // America/Toronto [backzone]
"America/Yellowknife", // America/Edmonton [backzone]
"Asia/Chongqing", // Asia/Shanghai [backzone]
"Asia/Harbin", // Asia/Shanghai [backzone]
"Asia/Ho_Chi_Minh", // Asia/Saigon [asia]
"Asia/Kashgar", // Asia/Urumqi [backzone]
"Asia/Kathmandu", // Asia/Katmandu [asia]
"Asia/Kolkata", // Asia/Calcutta [asia]
"Asia/Tel_Aviv", // Asia/Jerusalem [backzone]
"Asia/Yangon", // Asia/Rangoon [asia]
"Atlantic/Faroe", // Atlantic/Faeroe [europe]
"Atlantic/Jan_Mayen", // Arctic/Longyearbyen [backzone]
"Australia/Currie", // Australia/Hobart [backzone]
"CET", // Europe/Brussels [backzone]
"CST6CDT", // America/Chicago [backzone]
"EET", // Europe/Athens [backzone]
"EST", // America/Panama [backzone]
"EST5EDT", // America/New_York [backzone]
"Europe/Belfast", // Europe/London [backzone]
"Europe/Kyiv", // Europe/Kiev [europe]
"Europe/Tiraspol", // Europe/Chisinau [backzone]
"Europe/Uzhgorod", // Europe/Kiev [backzone]
"Europe/Zaporozhye", // Europe/Kiev [backzone]
"Factory", // Etc/Unknown [factory]
"HST", // Pacific/Honolulu [backzone]
"MET", // Europe/Brussels [backzone]
"MST", // America/Phoenix [backzone]
"MST7MDT", // America/Denver [backzone]
"PST8PDT", // America/Los_Angeles [backzone]
"Pacific/Chuuk", // Pacific/Truk [backzone]
"Pacific/Johnston", // Pacific/Honolulu [backzone]
"Pacific/Chuuk", // Pacific/Truk [backward]
"Pacific/Kanton", // Pacific/Enderbury [australasia]
"Pacific/Pohnpei", // Pacific/Ponape [backzone]
"WET", // Europe/Lisbon [backzone]
"Pacific/Pohnpei", // Pacific/Ponape [backward]
"UTC", // Etc/UTC [backward]
};

// Format:
Expand All @@ -74,38 +42,49 @@ struct LinkAndTarget

const LinkAndTarget ianaLinksCanonicalizedDifferentlyByICU[] = {
{ "Africa/Asmera", "Africa/Asmara" }, // Africa/Asmera [backward]
{ "America/Argentina/ComodRivadavia", "America/Argentina/Catamarca" }, // America/Catamarca [backward]
{ "America/Buenos_Aires", "America/Argentina/Buenos_Aires" }, // America/Buenos_Aires [backward]
{ "America/Catamarca", "America/Argentina/Catamarca" }, // America/Catamarca [backward]
{ "America/Coral_Harbour", "America/Atikokan" }, // America/Coral_Harbour [backward]
{ "America/Cordoba", "America/Argentina/Cordoba" }, // America/Cordoba [backward]
{ "America/Fort_Wayne", "America/Indiana/Indianapolis" }, // America/Indianapolis [backward]
{ "America/Godthab", "America/Nuuk" }, // America/Godthab [backward]
{ "America/Indianapolis", "America/Indiana/Indianapolis" }, // America/Indianapolis [backward]
{ "America/Jujuy", "America/Argentina/Jujuy" }, // America/Jujuy [backward]
{ "America/Kralendijk", "America/Curacao" }, // America/Kralendijk [backward]
{ "America/Louisville", "America/Kentucky/Louisville" }, // America/Louisville [backward]
{ "America/Lower_Princes", "America/Curacao" }, // America/Lower_Princes [backward]
{ "America/Marigot", "America/Port_of_Spain" }, // America/Marigot [backward]
{ "America/Mendoza", "America/Argentina/Mendoza" }, // America/Mendoza [backward]
{ "America/St_Barthelemy", "America/Port_of_Spain" }, // America/St_Barthelemy [backward]
{ "America/Rosario", "America/Argentina/Cordoba" }, // America/Cordoba [backward]
{ "Antarctica/South_Pole", "Antarctica/McMurdo" }, // Pacific/Auckland [backward]
{ "Arctic/Longyearbyen", "Europe/Oslo" }, // Arctic/Longyearbyen [backward]
{ "Asia/Calcutta", "Asia/Kolkata" }, // Asia/Calcutta [backward]
{ "Asia/Chungking", "Asia/Chongqing" }, // Asia/Shanghai [backward]
{ "Asia/Katmandu", "Asia/Kathmandu" }, // Asia/Katmandu [backward]
{ "Asia/Rangoon", "Asia/Yangon" }, // Asia/Rangoon [backward]
{ "Asia/Saigon", "Asia/Ho_Chi_Minh" }, // Asia/Saigon [backward]
{ "Atlantic/Faeroe", "Atlantic/Faroe" }, // Atlantic/Faeroe [backward]
{ "Europe/Bratislava", "Europe/Prague" }, // Europe/Bratislava [backward]
{ "Europe/Busingen", "Europe/Zurich" }, // Europe/Busingen [backward]
{ "Etc/GMT", "UTC" }, // Etc/GMT [etcetera]
{ "Etc/GMT+0", "UTC" }, // Etc/GMT [backward]
{ "Etc/GMT-0", "UTC" }, // Etc/GMT [backward]
{ "Etc/GMT0", "UTC" }, // Etc/GMT [backward]
{ "Etc/Greenwich", "UTC" }, // Etc/GMT [backward]
{ "Etc/UCT", "UTC" }, // Etc/UTC [backward]
{ "Etc/UTC", "UTC" }, // Etc/UTC [etcetera]
{ "Etc/Universal", "UTC" }, // Etc/UTC [backward]
{ "Etc/Zulu", "UTC" }, // Etc/UTC [backward]
{ "Europe/Kiev", "Europe/Kyiv" }, // Europe/Kiev [backward]
{ "Europe/Mariehamn", "Europe/Helsinki" }, // Europe/Mariehamn [backward]
{ "Europe/Podgorica", "Europe/Belgrade" }, // Europe/Podgorica [backward]
{ "Europe/San_Marino", "Europe/Rome" }, // Europe/San_Marino [backward]
{ "Europe/Vatican", "Europe/Rome" }, // Europe/Vatican [backward]
{ "Europe/Uzhgorod", "Europe/Kyiv" }, // Europe/Kiev [backward]
{ "Europe/Zaporozhye", "Europe/Kyiv" }, // Europe/Kiev [backward]
{ "GMT", "UTC" }, // Etc/GMT [etcetera]
{ "GMT+0", "UTC" }, // Etc/GMT [backward]
{ "GMT-0", "UTC" }, // Etc/GMT [backward]
{ "GMT0", "UTC" }, // Etc/GMT [backward]
{ "Greenwich", "UTC" }, // Etc/GMT [backward]
{ "Pacific/Enderbury", "Pacific/Kanton" }, // Pacific/Enderbury [backward]
{ "Pacific/Ponape", "Pacific/Pohnpei" }, // Pacific/Ponape [backward]
{ "Pacific/Truk", "Pacific/Chuuk" }, // Pacific/Truk [backward]
{ "Pacific/Yap", "Pacific/Chuuk" }, // Pacific/Truk [backward]
{ "UCT", "UTC" }, // Etc/UTC [backward]
{ "US/East-Indiana", "America/Indiana/Indianapolis" }, // America/Indianapolis [backward]
{ "Universal", "UTC" }, // Etc/UTC [backward]
{ "Zulu", "UTC" }, // Etc/UTC [backward]
};

// Legacy ICU time zones, these are not valid IANA time zone names. We also
Expand Down Expand Up @@ -139,6 +118,7 @@ const char* const legacyICUTimeZones[] = {
"SST",
"US/Pacific-New",
"VST",
"Factory",
"SystemV/AST4",
"SystemV/AST4ADT",
"SystemV/CST6",
Expand Down
157 changes: 157 additions & 0 deletions js/src/builtin/intl/TimeZoneMapping.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

# Provide mapping from time zone identifiers to region codes for time zones
# which aren't listed in tzdata's zone.tab file.

Africa/Timbuktu: ML
Africa/Asmera: ER

America/Argentina/ComodRivadavia: AR
America/Atka: US
America/Buenos_Aires: AR
America/Catamarca: AR
America/Coral_Harbour: CA
America/Cordoba: AR
America/Ensenada: MX
America/Fort_Wayne: US
America/Godthab: GL
America/Indianapolis: US
America/Jujuy: AR
America/Knox_IN: US
America/Louisville: US
America/Mendoza: AR
America/Montreal: CA
America/Nipigon: CA
America/Pangnirtung: CA
America/Porto_Acre: BR
America/Rainy_River: CA
America/Rosario: AR
America/Santa_Isabel: MX
America/Shiprock: US
America/Thunder_Bay: CA
America/Virgin: VI
America/Yellowknife: CA

Antarctica/South_Pole: AQ

Asia/Choibalsan: MN
Asia/Chongqing: CN
Asia/Harbin: CN
Asia/Kashgar: CN
Asia/Tel_Aviv: IL
Asia/Ashkhabad: TM
Asia/Calcutta: IN
Asia/Chungking: CN
Asia/Dacca: BD
Asia/Istanbul: TR
Asia/Katmandu: NP
Asia/Macao: MO
Asia/Rangoon: MM
Asia/Saigon: VN
Asia/Thimbu: BT
Asia/Ujung_Pandang: ID
Asia/Ulan_Bator: MN

Atlantic/Jan_Mayen: SJ
Atlantic/Faeroe: FO

Australia/ACT: AU
Australia/LHI: AU
Australia/NSW: AU
Australia/Canberra: AU
Australia/Currie: AU
Australia/North: AU
Australia/Queensland: AU
Australia/South: AU
Australia/Tasmania: AU
Australia/Victoria: AU
Australia/West: AU
Australia/Yancowinna: AU

Europe/Belfast: GB
Europe/Tiraspol: MD
Europe/Uzhgorod: UA
Europe/Zaporozhye: UA
Europe/Kiev: UA
Europe/Nicosia: CY

Pacific/Samoa: AS
Pacific/Enderbury: KI
Pacific/Johnston: US
Pacific/Yap: FM
Pacific/Ponape: FM
Pacific/Truk: FM

Brazil/Acre: BR
Brazil/DeNoronha: BR
Brazil/East: BR
Brazil/West: BR

Canada/Atlantic: CA
Canada/Central: CA
Canada/Eastern: CA
Canada/Mountain: CA
Canada/Newfoundland: CA
Canada/Pacific: CA
Canada/Saskatchewan: CA
Canada/Yukon: CA

Chile/Continental: CL
Chile/EasterIsland: CL

Mexico/BajaNorte: MX
Mexico/BajaSur: MX
Mexico/General: MX

US/Alaska: US
US/Aleutian: US
US/Arizona: US
US/Central: US
US/East-Indiana: US
US/Eastern: US
US/Hawaii: US
US/Indiana-Starke: US
US/Michigan: US
US/Mountain: US
US/Pacific: US
US/Samoa: AS

CET: BE
EET: GR
MET: BE
WET: PT

CST6CDT: US
EST5EDT: US
EST: PA
HST: US
MST7MDT: US
MST: US
PST8PDT: US

Cuba: CU
Egypt: EG
Eire: IE
GB: GB
GB-Eire: GB
Hongkong: HK
Iceland: IS
Iran: IR
Israel: IL
Jamaica: JM
Japan: JP
Kwajalein: MH
Libya: LY
NZ: NZ
NZ-CHAT: NZ
Navajo: US
PRC: CN
Poland: PL
Portugal: PT
ROC: TW
ROK: KR
Singapore: SG
Turkey: TR
W-SU: RU
Loading

0 comments on commit 0b0c4f8

Please sign in to comment.