From 86064077f184d6778c664dd785d119a812312514 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sat, 24 Oct 2026 15:04:35 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20ISOWEEKNUM/WEEKNUM(=E2=80=A6,21)=20for=20?= =?UTF-8?q?the=20first=20days=20of=20the=20calendar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found while testing crates/functions/src/date.rs:123-129 (isoweek) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/functions/src/date.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/crates/functions/src/date.rs b/crates/functions/src/date.rs index 05638b2b7..a763b0c0c 100644 --- a/crates/functions/src/date.rs +++ b/crates/functions/src/date.rs @@ -123,8 +123,16 @@ fn weekday(a: &[Arg], c: &mut dyn Ctx) -> R { fn isoweek(sys: DateSystem, s: i64) -> R { let iso_wd = (weekday0(sys, s) + 6) % 7 + 1; // Monday = 1 let thursday = s - iso_wd as i64 + 4; - let y = if thursday < 1 { 1900 } else { dt(sys, thursday as f64)?.year as i64 }; - let jan1 = ymd_serial(sys, y, 1, 1)?; + let first = match sys { + DateSystem::D1900 => 1, + DateSystem::D1904 => 0, + }; + let jan1 = if thursday < first { + // The week belongs to the year before the calendar starts. + first - 365 + } else { + ymd_serial(sys, dt(sys, thursday as f64)?.year as i64, 1, 1)? + }; Ok((thursday - jan1).div_euclid(7) + 1) } @@ -844,6 +852,19 @@ mod tests { is_err(crate::call(spec, &[t("2/29/1900")], &mut ctx), CellError::Value); } + #[test] + fn isoweek_at_calendar_start() { + let iso = crate::lookup("ISOWEEKNUM").unwrap(); + let wk = crate::lookup("WEEKNUM").unwrap(); + let mut ctx = TestCtx::default(); + close(crate::call(iso, &[n(1.0)], &mut ctx), 52.0); + close(crate::call(wk, &[n(1.0), n(21.0)], &mut ctx), 52.0); + let mut ctx = TestCtx { sys: gridcraft_core::DateSystem::D1904, ..TestCtx::default() }; + for s in [0.0, 1.0, 2.0] { + close(crate::call(iso, &[n(s)], &mut ctx), 53.0); + } + } + #[test] fn date_text_arguments_use_the_workbook_date_system() { let mut ctx = TestCtx { sys: gridcraft_core::DateSystem::D1904, ..TestCtx::default() };