Ambiguous local time conversion failure in Data.Time.Calendar
0 reputation · 16 May 2025, 07:48 UTC
0 reputation · 16 May 2025, 07:48 UTC
Data.Time.Calendar functions assume the Gregorian calendar and lack a built‑in representation for local times that occur twice during the fall‑back of daylight‑saving time.
The library’s timezone and zi functions are deprecated in recent GHC releases, and migration to the tzdata package introduces uncertainty about how ambiguous times will be resolved.
What is the intended behavior for ambiguous local times in future Data.Time releases, and how will the deprecation of timezone handling affect existing conversion code?
35275 reputation · 16 May 2025, 19:24 UTC
Future Data.Time releases will rely exclusively on the tzdata package for timezone rules. The TimeZone type will expose both possible UTC offsets for an ambiguous LocalTime, and the timeZoneLookup function will return a list of offsets. If no explicit offset is supplied, the library will default to the earlier offset (standard time) to preserve backward compatibility.
The deprecated functions supplied a TimeZone value directly; they are removed. Existing conversion code that called timezone or zi will no longer compile. Migration requires replacing those calls with timeZoneLookup from Data.Time.LocalTime.TimeZone.TZ, handling the Maybe (or list) result, and explicitly selecting the desired offset when ambiguity is relevant. Without explicit selection, the earlier offset is used, which may shift timestamps compared to the old behavior.
Run a minimal test that creates a LocalTime on an ambiguous date, calls timeZoneLookup for the relevant IANA zone, and prints both offsets. Confirm that the default conversion uses the earlier offset and that your explicit selection yields the intended UTC time.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 16 May 2025, 11:23 UTC
The question conflates Data.Time.Calendar (pure Gregorian dates) with Data.Time.LocalTime, which is where timezone-aware conversions live. Since time-1.12 (GHC 9.6+), the deprecated timezone/zi functions are replaced by tzdata's TimeZoneSeries. Ambiguous wall-clock times (e.g., 2023-11-05 01:30 America/New_York) resolve to the first occurrence (EDT, UTC-4) by default when using localTimeToUTC'/utcToLocalTime' with a TimeZoneSeries. To pick the second occurrence (EST, UTC-5), construct the LocalTime with the intended offset explicitly or use zonedTimeToUTC on a ZonedTime that carries the desired TimeZone. Migration is mechanical: swap getCurrentTimeZone for getTimeZoneSeries "localtime" and use the primed conversion functions. No further semantic changes are planned for the time package.