Keep seconds in FormCalc Time2Num/IsoTime2Num for ISO 8601 times

Found while testing crates/js/src/formcalc.rs:2348-2352 ("time2num" | "isotime2num")

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-17 02:24:39 +00:00
co-authored by Claude Haiku 5.5
parent 924c4da4ac
commit 5157e0421b
2 changed files with 13 additions and 3 deletions
+10 -3
View File
@@ -2347,9 +2347,16 @@ impl Interp<'_> {
}
"time2num" | "isotime2num" => {
let s = self.arg_str(args, 0)?;
let parts: Vec<u64> = s.split(':').filter_map(|p| p.trim().parse::<u64>().ok()).map(|v| v.min(1_000_000)).collect();
let (h, m, sec) = (parts.first().copied().unwrap_or(0), parts.get(1).copied().unwrap_or(0), parts.get(2).copied().unwrap_or(0));
Val::Num(((h * 3600 + m * 60 + sec) * 1000) as f64)
// ISO 8601 allows a leading "T", a trailing "Z" and fractional seconds.
let t = s.trim();
let t = t.strip_prefix(['T', 't']).unwrap_or(t);
let t = t.strip_suffix(['Z', 'z']).unwrap_or(t);
let mut parts = t.split(':');
let mut whole = || parts.next().and_then(|p| p.trim().parse::<u64>().ok()).unwrap_or(0).min(1_000_000);
let (h, m) = (whole(), whole());
let sec =
parts.next().and_then(|p| p.trim().parse::<f64>().ok()).filter(|v| v.is_finite() && *v >= 0.0).unwrap_or(0.0).min(1_000_000.0);
Val::Num(((h * 3600 + m * 60) * 1000) as f64 + (sec * 1000.0).round())
}
// ── financial
"fv" => {
+3
View File
@@ -680,6 +680,9 @@ mod formcalc {
assert_eq!(calc(r#"Num2Date(45350, "YYYY-MM-DD")"#), "2024-02-29");
assert_eq!(calc(r#"Num2Date(Date2Num("2024-02-29") + 1, "MMMM D, YYYY")"#), "March 1, 2024");
assert_eq!(calc(r#"Time2Num("01:00:00")"#), "3600000");
assert_eq!(calc(r#"IsoTime2Num("12:30:45Z")"#), "45045000");
assert_eq!(calc(r#"IsoTime2Num("12:30:45.250")"#), "45045250");
assert_eq!(calc(r#"IsoTime2Num("T12:30:45")"#), "45045000");
assert_eq!(calc(r#"Num2Time(3661000)"#), "01:01:01");
assert_eq!(calc("Round(Pmt(10000, 0.01, 12), 2)"), "888.49");
assert_eq!(calc("Round(FV(100, 0.01, 12), 2)"), "1268.25");