From 8f9338a5ec19188c8a4732682e23858244358077 Mon Sep 17 00:00:00 2001 From: Anirudh Sharma Date: Tue, 13 Oct 2026 14:21:00 +0530 Subject: [PATCH] fix(fill): respect workbook date system in monthly autofill --- crates/engine/src/fill.rs | 7 ++++--- crates/engine/src/tests.rs | 27 +++++++++++++++++++++++++++ docs/ui-parity.md | 5 +++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/crates/engine/src/fill.rs b/crates/engine/src/fill.rs index 5848bb0ca..3cd4570aa 100644 --- a/crates/engine/src/fill.rs +++ b/crates/engine/src/fill.rs @@ -165,6 +165,7 @@ enum Pattern { last: f64, first: f64, months: i64, + sys: gridcraft_core::DateSystem, }, } @@ -199,7 +200,7 @@ impl Pattern { && (a.month != b.month || a.year != b.year) { let months = (b.year as i64 - a.year as i64) * 12 + b.month as i64 - a.month as i64; - return Pattern::Months { last, first, months }; + return Pattern::Months { last, first, months, sys }; } } // Least-squares step for 2+ values (Excel uses a linear trend). @@ -297,9 +298,9 @@ impl Pattern { s })) } - Pattern::Months { last, first, months } => { + Pattern::Months { last, first, months, sys } => { let base = if forward { *last } else { *first }; - let s = add_months_clamped(gridcraft_core::DateSystem::D1900, base, months.checked_mul(k * sign)?)?; + let s = add_months_clamped(*sys, base, months.checked_mul(k * sign)?)?; Some(Value::number(s)) } } diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index ae499a189..68ee3632c 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -2897,6 +2897,33 @@ fn fill_series_year_clamps_leap_day() { assert_eq!(v(&s, "A5"), ymd(2032, 2, 29)); } +#[test] +fn autofill_month_pattern_uses_workbook_date_system() { + use std::sync::Arc; + + use gridcraft_core::date::serial_from_ymd; + use gridcraft_core::{DateSystem, RangeRef}; + + for sys in [DateSystem::D1900, DateSystem::D1904] { + for (source, target, seeds, expected) in [ + ("A1:A2", "A1:A6", ["2026-01-31", "2026-03-31"], ["2026-01-31", "2026-03-31", "2026-05-31", "2026-07-31", "2026-09-30", "2026-11-30"]), + ("A5:A6", "A1:A6", ["2026-09-30", "2026-11-30"], ["2026-01-30", "2026-03-30", "2026-05-30", "2026-07-30", "2026-09-30", "2026-11-30"]), + ] { + let mut s = s(); + Arc::make_mut(&mut s.doc_mut().unwrap().wb).date_system = sys; + let start = RangeRef::parse(source).unwrap().start.a1(); + s.execute("range.setValues", json!({"range": start, "values": [[seeds[0]], [seeds[1]]]})).unwrap(); + s.execute("edit.autoFill", json!({"source": source, "target": target})).unwrap(); + for (row, date) in expected.iter().enumerate() { + let parts: Vec = date.split('-').map(|p| p.parse().unwrap()).collect(); + let expected = Value::Number(serial_from_ymd(sys, parts[0], parts[1], parts[2]).unwrap()); + let cell = CellRef::new(row as u32, 0).a1(); + assert_eq!(v(&s, &cell), expected, "{sys:?} {source} -> {target}, {cell}: {date}"); + } + } + } +} + #[test] fn autofill_month_pattern_clamps_to_month_end() { let mut s = s(); diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 22e221e69..a1e74f50f 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -1,6 +1,6 @@ # UI parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (horizontal scrollbar in the sheet tab bar, #840) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (AutoFill month patterns respect the workbook's date system) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 Interaction, controls and feel, against Excel. Part of [target-app-parity.md](target-app-parity.md). **UI/UX fidelity: ~55% ready, 50–80 h** (estimated). Ribbon command coverage is measured @@ -45,7 +45,7 @@ this logic, with one undo step. |---|---| | Click/drag/Shift/Ctrl selection, multi-area selection | rectangular drag works in one direction only in some cases (#28) | | Selection outline glides to a new selection (Excel: "Provide feedback with animation") | done (10-11): 0.12 s, decelerating, with the fill and fill handle; View ▸ Animations (`view.animations`) turns it off. The timing is an estimate, not yet measured against Excel; the system's reduced-motion setting isn't followed yet | -| Fill handle: drag to fill series, double-click to fill down, right-drag menu | fill done (Ctrl+drag swaps copy and series); right-drag menu missing | +| Fill handle: drag to fill series, double-click to fill down, right-drag menu | fill done (Ctrl+drag swaps copy and series); month patterns use the workbook's 1900 or 1904 date system; right-drag menu missing | | Drag-move and drag-copy cells (border drag, Ctrl/Option, Shift to insert) | done (M3) | | In-cell editing, Enter/Tab movement, Alt/Option+Enter line breaks | done | | Point mode (click/drag/arrow references), reference colouring, F4 | done | @@ -161,6 +161,7 @@ scrollbar bugs 2–4 · pixel/feel pass against observed Excel 7–12. | Date | Change | Summary | |---|---|---| +| 2026-10-13 | minor | AutoFill month patterns retain the workbook's date system, preventing shifted dates in 1904 workbooks when filling forward or backward | | 2026-10-12 | minor | The File view's recent list tells when each workbook was last changed, read off the UI thread | | 2026-10-13 | minor | Horizontal scrollbar in the sheet tab bar: drag, track click pages, frozen columns excluded from the page (#840) | | 2026-10-12 | minor | Ctrl+wheel zoom steps along a ladder of percentages about 20% apart that never skips 100%, gliding to each step with animations on, so a notch out undoes a notch in (it drifted: 100 → 122 → 101); Excel steps 15 points, see decisions.md |