From 20486cd615f322b11048d524dab27f329c6383e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E7=89=B9=E6=AF=8F=E7=BE=8A=E9=98=9F?= Date: Wed, 12 Aug 2026 13:31:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20PlainDate/PlainDateTime=20until/since=20?= =?UTF-8?q?=E6=9C=88=E5=88=86=E8=A7=A3=20days=20=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=EF=BC=88current=20=E4=BF=9D=E6=8C=81=E7=9C=9F=E5=AE=9E?= =?UTF-8?q?=E9=92=B3=E5=88=B6=E6=97=A5=E6=9C=9F=EF=BC=8C=E9=94=9A=E5=AE=9A?= =?UTF-8?q?=E6=97=A5=E5=8F=AA=E7=94=A8=E4=BA=8E=E8=B6=8A=E7=95=8C=E6=AF=94?= =?UTF-8?q?=E8=BE=83=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_builtins/src/temporal.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/oxide_builtins/src/temporal.rs b/crates/oxide_builtins/src/temporal.rs index 62b5f09..49edb2a 100644 --- a/crates/oxide_builtins/src/temporal.rs +++ b/crates/oxide_builtins/src/temporal.rs @@ -3255,16 +3255,18 @@ fn date_until_iso(start: (i128, i128, i128), end: (i128, i128, i128), largest: u if surpasses_with_day(sign, intermediate, start.2, end) { years -= sign; } - let mut current: (i128, i128, i128); - let mut next = add_months_i128(start.0, start.1, start.2, years * 12 + months); + // 从 start 按锚定日逐月推进(月末钳制);current 始终是未越界的真实日期, + // 锚定日覆盖只用于越界比较,避免伪日期(如 2 月 29 日)污染天数计算。 + let mut current = add_months_i128(start.0, start.1, start.2, years * 12 + months); loop { months += sign; - current = next; - next = add_months_i128(current.0, current.1, current.2, sign); - next.2 = start.2; - if surpasses_with_day(sign, next, start.2, end) { + let candidate = add_months_i128(start.0, start.1, start.2, years * 12 + months); + let mut cmp = candidate; + cmp.2 = start.2; + if surpasses_with_day(sign, cmp, start.2, end) { break; } + current = candidate; } months -= sign; let days = days_from_civil(end.0, end.1, end.2) - days_from_civil(current.0, current.1, current.2);