Skip to main content

resolve_local_offset

Function resolve_local_offset 

Source
pub(crate) fn resolve_local_offset<T: TimeZone>(
    tz: &T,
    local: &NaiveDateTime,
) -> Option<T::Offset>
Expand description

Returns the offset to use when interpreting local as a wall clock reading in tz, or None if it cannot be resolved.

In an IANA timezone a wall clock reading does not always identify a unique instant, and this function picks one following the same rules as PostgreSQL and DuckDB:

  • Ambiguous – when the clocks go back (“fall back”) the same reading occurs twice. The later instant is chosen, i.e. the offset in effect after the transition. For example 2024-11-03T01:30:00 in America/New_York is read as -05:00 (EST), not -04:00 (EDT).
  • Nonexistent – when the clocks go forward (“spring forward”) the reading never occurs. It is shifted forward by the length of the gap, which is the same as reading it with the offset in effect before the transition. For example 2024-03-10T02:30:00 in America/New_York is read as -05:00 (EST) and therefore denotes 2024-03-10T03:30:00-04:00.

Timezones with a fixed offset are never ambiguous and have no gaps.

The gap rule probes the offset 24 hours earlier. This is correct for the IANA timezone database, but this function accepts any TimeZone. For a timezone whose transitions do not obey the assumptions given in the body (no gap longer than 24 hours, no two transitions closer than 24 hours), the result can be None or an incorrect offset.

None is therefore not expected in practice: with the current timezone database every ambiguous or nonexistent reading resolves as described above, and the None path is only a safeguard. Callers then apply their usual error or null handling.

See https://github.com/apache/arrow-rs/issues/11037 for the PostgreSQL and ICU (DuckDB) sources these rules are taken from.