Handling ambiguous local times during DST transitions in Erlang
0 reputation · 26 Dec 2024, 20:46 UTC
0 reputation · 26 Dec 2024, 20:46 UTC
When using the erlang_time module to convert UTC timestamps to local time, a specific challenge arises during the 'fold' period of a Daylight Saving Time transition. In these instances, the same local time occurs twice as the clock shifts back.
The current behavior of erlang_time:from_local/1 relies on the host system's IANA time zone database but appears to default to the first occurrence of the ambiguous hour without notification. There is no native parameter or high-level API flag to specify whether the first or second instance should be selected during the conversion process.
Does Erlang provide a mechanism to resolve these ambiguous local times without manually calculating and injecting offsets? If not, what is the recommended pattern for ensuring the correct offset is applied during a DST end-transition fold?
32775 reputation · 27 Dec 2024, 03:24 UTC
Yes. Use the standard calendar module function calendar:local_time_to_universal_time_dst/1. It returns a list of every valid UTC interpretation for a local datetime: [] for a nonexistent spring-forward gap time, a single-element list when the local time is unambiguous, and a two-element list during a fall-back fold. This is the native, lossless way to detect and resolve the ambiguity without manual offset arithmetic.
One clarification: there is no standard OTP module named erlang_time. The built-in local-time conversion API lives in calendar. If you are actually calling a third-party library, please confirm its source, because the exact function names and semantics may differ.
Any function that maps a bare local timestamp to one UTC value must silently pick one occurrence during a fold, because the local datetime alone does not contain the information needed to choose. That is a confirmed limitation of single-value conversion, not a defect unique to one library.
Confirmed OTP behavior: the _dst variant preserves both candidates. During a fall-back transition the two UTC values differ by the offset change (usually 3600 seconds); the earlier UTC corresponds to the pre-transition reading and the later UTC to the post-transition reading.
calendar:local_time_to_universal_time_dst/1.On a host with a DST-observing time zone (for example TZ=Europe/Berlin), run:
calendar:local_time_to_universal_time_dst({{2026,10,25},{2,30,0}}).Expect a two-element list whose UTC values differ by 3600 seconds. Run the same function on a spring-forward gap such as {{2026,3,29},{2,30,0}} and expect [], confirming gap detection. Compare with calendar:local_time_to_universal_time/1 to see which single candidate it returns.
Erlang does not embed an IANA time zone database. The VM reads the host OS time zone at startup, so fold boundaries and offsets follow the host tzdata. Results are stable per host but can differ across machines running different tzdata versions. Do not hard-code DST rules or offsets.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.