From 0e17ab00b04255690a3dfac32aef50a2dac22553 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 9 Mar 2026 17:02:29 -0400 Subject: [PATCH] store: handle DST gaps in epoch_to_local chrono's timestamp_opt can return None during DST transitions. Handle all three variants (Single, Ambiguous, None) instead of unwrapping. For DST gaps, offset by one hour to land in valid local time. Co-Authored-By: ProofOfConcept --- poc-memory/src/store/types.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/poc-memory/src/store/types.rs b/poc-memory/src/store/types.rs index d5164f8..691b49a 100644 --- a/poc-memory/src/store/types.rs +++ b/poc-memory/src/store/types.rs @@ -129,7 +129,16 @@ pub fn now_epoch() -> i64 { /// Returns (year, month, day, hour, minute, second). pub fn epoch_to_local(epoch: i64) -> (i32, u32, u32, u32, u32, u32) { use chrono::{Datelike, Local, TimeZone, Timelike}; - let dt = Local.timestamp_opt(epoch, 0).unwrap(); + let dt = match Local.timestamp_opt(epoch, 0) { + chrono::LocalResult::Single(dt) => dt, + chrono::LocalResult::Ambiguous(dt, _) => dt, + chrono::LocalResult::None => { + // DST gap — add an hour to land in valid local time + Local.timestamp_opt(epoch + 3600, 0) + .earliest() + .unwrap_or_else(|| chrono::Utc.timestamp_opt(epoch, 0).unwrap().with_timezone(&Local)) + } + }; ( dt.year(), dt.month(),