feat(timezone): add Windows timezone name resolution

Add a `Windows_tz` module containing a CLDR-sourced mapping table from
Windows timezone names to canonical IANA names. Update
`timedesc_of_timestamp` to resolve Windows-style timezone identifiers
(e.g. `"W. Europe Standard Time"`) via this table before constructing a
`Timedesc.Time_zone.t`, falling back to the local timezone with a
warning if resolution fails entirely.
This commit is contained in:
2026-05-19 23:56:54 +02:00
parent d961a9f32a
commit dc11e077bf
3 changed files with 162 additions and 2 deletions

View File

@@ -105,7 +105,18 @@ let timedesc_of_timestamp (ts : timestamp) : Timedesc.t =
| `With_tzid (ts, (_b, tz_name)) ->
(* The timestamp is stored as if it were UTC but must be interpreted in tz_name.
We reconstruct the wall-clock time in tz_name, then convert to target_tz. *)
let tz = Timedesc.Time_zone.make_exn tz_name in
(* Resolve the timezone name: Windows names (e.g. "W. Europe Standard Time") are
mapped to IANA via the CLDR table; otherwise the name is used as-is (assumed
to already be a valid IANA name). If resolution fails entirely, fall back to
target_tz with a warning. *)
let tz =
let candidate = Option.value ~default:tz_name (Windows_tz.to_iana tz_name) in
match Timedesc.Time_zone.make candidate with
| Some tz -> tz
| None ->
Printf.eprintf "Warning: unresolvable timezone %S, falling back to local timezone\n" tz_name;
!target_tz
in
let wrong_ts = Timedesc.Utils.timestamp_of_ptime ts in
let date = Timedesc.date (Timedesc.of_timestamp_exn ~tz_of_date_time:Timedesc.Time_zone.utc wrong_ts) in
let year, month, day = (Timedesc.Date.year date, Timedesc.Date.month date, Timedesc.Date.day date) in