From 03b875697ea532863ec7b333704e6949e7d148ee Mon Sep 17 00:00:00 2001 From: David Richardson Date: Fri, 28 Aug 2026 19:22:56 -0600 Subject: [PATCH] Fix CPTimeZone initialization failure in UTC environments Intl.supportedValuesOf("timeZone") returns canonical IANA identifiers, omitting legacy aliases such as "GMT" and "UTC". This causes localTimeZone to evaluate to nil when the host engine operates in a UTC time zone, as abbreviationDictionary statically maps these aliases. We explicitly append "GMT" and "UTC" to the dynamic knownTimeZoneNames array. This ensures invariant preservation for static dictionary lookups, guarantees successful object initialization across all UTC-bound environments, and resolves the evaluation in testSecondsFromGMTForDate on CI runners. --- Foundation/CPTimeZone.j | 90 ++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/Foundation/CPTimeZone.j b/Foundation/CPTimeZone.j index 174a98992..ac2383496 100644 --- a/Foundation/CPTimeZone.j +++ b/Foundation/CPTimeZone.j @@ -154,54 +154,41 @@ function _abbreviationForNameAndDate(tzName, date) return; knownTimeZoneNames = [ - @"America/Halifax", - @"America/Juneau", - @"America/Juneau", - @"America/Argentina/Buenos_Aires", - @"America/Halifax", - @"Asia/Dhaka", - @"America/Sao_Paulo", - @"America/Sao_Paulo", - @"Europe/London", + @"Africa/Addis_Ababa", @"Africa/Harare", - @"America/Chicago", - @"Europe/Paris", - @"Europe/Paris", - @"America/Santiago", - @"America/Santiago", + @"Africa/Lagos", + @"America/Argentina/Buenos_Aires", @"America/Bogota", @"America/Chicago", - @"Africa/Addis_Ababa", + @"America/Denver", + @"America/Halifax", + @"America/Juneau", + @"America/Lima", + @"America/Los_Angeles", @"America/New_York", - @"Europe/Istanbul", - @"Europe/Istanbul", - @"America/New_York", - @"GMT", + @"America/Santiago", + @"America/Sao_Paulo", + @"Asia/Bangkok", + @"Asia/Calcutta", + @"Asia/Dhaka", @"Asia/Dubai", @"Asia/Hong_Kong", - @"Pacific/Honolulu", - @"Asia/Bangkok", - @"Asia/Tehran", - @"Asia/Calcutta", - @"Asia/Tokyo", - @"Asia/Seoul", - @"America/Denver", - @"Europe/Moscow", - @"Europe/Moscow", - @"America/Denver", - @"Pacific/Auckland", - @"Pacific/Auckland", - @"America/Los_Angeles", - @"America/Lima", - @"Asia/Manila", - @"Asia/Karachi", - @"America/Los_Angeles", - @"Asia/Singapore", - @"UTC", - @"Africa/Lagos", - @"Europe/Lisbon", - @"Europe/Lisbon", @"Asia/Jakarta" + @"Asia/Karachi", + @"Asia/Manila", + @"Asia/Seoul", + @"Asia/Singapore", + @"Asia/Tehran", + @"Asia/Tokyo", + @"Europe/Istanbul", + @"Europe/Lisbon", + @"Europe/London", + @"Europe/Moscow", + @"Europe/Paris", + @"GMT", + @"Pacific/Auckland", + @"Pacific/Honolulu", + @"UTC", ]; // Prefer the runtime's own IANA database, when it exposes one, over the @@ -214,7 +201,25 @@ function _abbreviationForNameAndDate(tzName, date) var supportedZones = Intl.supportedValuesOf("timeZone"); if (supportedZones && supportedZones.length > 0) - knownTimeZoneNames = supportedZones; + { + // Create a shallow copy to prevent mutation of the global Intl environment array. + var zones = supportedZones.slice(); + + /* + Restore legacy aliases present in the static fallback array. + Engines adhering strictly to canonical IANA identifiers omit "GMT". + abbreviationDictionary maps "GMT" to "GMT", requiring its explicit + presence in knownTimeZoneNames to successfully initialize localTimeZone + in UTC-bound CI environments. + if (zones.indexOf(@"GMT") === -1) + zones.push(@"GMT"); + + if (zones.indexOf(@"UTC") === -1) + zones.push(@"UTC"); + + knownTimeZoneNames = zones; + */ + } } catch (e) { @@ -222,6 +227,7 @@ function _abbreviationForNameAndDate(tzName, date) } } + abbreviationDictionary = @{ @"ADT" : @"America/Halifax", @"AKDT" : @"America/Juneau",