From 960c64c3e44de2c0ae99012d544b52f3278fed37 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sun, 25 Oct 2026 02:19:51 +0000 Subject: [PATCH] Return None from datetime_from_serial when rounding carries past 9999 Found while testing crates/core/src/date.rs:168-177 Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/core/src/date.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/core/src/date.rs b/crates/core/src/date.rs index b42c068a0..8e68695f1 100644 --- a/crates/core/src/date.rs +++ b/crates/core/src/date.rs @@ -174,6 +174,9 @@ pub fn datetime_from_serial(sys: DateSystem, serial: f64) -> Option { if frac_ms >= 86_400_000 { frac_ms -= 86_400_000; day += 1; + if day > max_serial(sys) { + return None; + } } let (y, m, d, weekday) = match sys { DateSystem::D1900 => { @@ -221,6 +224,14 @@ pub const WEEKDAYS: [&str; 7] = ["Sunday", "Monday", "Tuesday", "Wednesday", "Th mod tests { use super::*; + #[test] + fn serial_rounding_into_next_day_past_max_is_none() { + for sys in [DateSystem::D1900, DateSystem::D1904] { + let serial = max_serial(sys) as f64 + 0.9999999995; + assert_eq!(datetime_from_serial(sys, serial), None); + } + } + #[test] fn leap_and_month_length_outside_chrono_range() { // In range, the ordinary Gregorian rule holds.