pub type Day = i64;
pub fn days_from_civil(y: i64, m: i64, d: i64) -> Day {
let y = if m <= 2 { y - 1 } else { y };
let era = if y >= 0 { y } else { y - 399 } / 400;
let yoe = y - era * 400; let mp = (m + 9) % 12; let doy = (153 * mp + 2) / 5 + d - 1; let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; era * 146_097 + doe - 719_468
}
pub fn civil_from_days(z: Day) -> (i64, i64, i64) {
let z = z + 719_468;
let era = if z >= 0 { z } else { z - 146_096 } / 146_097;
let doe = z - era * 146_097;
let yoe = (doe - doe / 1460 + doe / 36524 - doe / 146_096) / 365;
let y = yoe + era * 400;
let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
let mp = (5 * doy + 2) / 153;
let d = doy - (153 * mp + 2) / 5 + 1;
let m = if mp < 10 { mp + 3 } else { mp - 9 };
(if m <= 2 { y + 1 } else { y }, m, d)
}
pub fn day_of(ts: &str) -> Option<Day> {
let b = ts.as_bytes();
if b.len() < 10 || b[4] != b'-' || b[7] != b'-' {
return None;
}
let num = |from: usize, to: usize| -> Option<i64> {
let mut n: i64 = 0;
for &c in &b[from..to] {
if !c.is_ascii_digit() {
return None;
}
n = n * 10 + i64::from(c - b'0');
}
Some(n)
};
let (y, m, d) = (num(0, 4)?, num(5, 7)?, num(8, 10)?);
if !(1..=12).contains(&m) || !(1..=31).contains(&d) {
return None;
}
Some(days_from_civil(y, m, d))
}
pub fn week_start(day: Day) -> Day {
day - (day + 3).rem_euclid(7)
}
pub fn iso(day: Day) -> String {
let (y, m, d) = civil_from_days(day);
format!("{y:04}-{m:02}-{d:02}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_calendar_agrees_with_known_dates() {
assert_eq!(days_from_civil(1970, 1, 1), 0);
assert_eq!(days_from_civil(1969, 12, 31), -1);
assert_eq!(days_from_civil(2000, 3, 1), 11017);
assert_eq!(days_from_civil(2000, 2, 29), 11016); assert_eq!(days_from_civil(2100, 3, 1), 47541);
assert_eq!(days_from_civil(2100, 2, 28), 47540); assert_eq!(days_from_civil(2026, 8, 20), 20685);
}
#[test]
fn every_day_round_trips_through_the_calendar() {
for day in -25_000..25_000 {
let (y, m, d) = civil_from_days(day);
assert_eq!(days_from_civil(y, m, d), day, "{y:04}-{m:02}-{d:02}");
}
}
#[test]
fn a_timestamp_yields_the_day_its_prefix_names() {
assert_eq!(day_of("2026-08-20T21:40:03.123Z"), Some(20685));
assert_eq!(day_of("2026-08-20"), Some(20685));
}
#[test]
fn an_unparseable_timestamp_is_not_a_guess() {
assert_eq!(day_of(""), None);
assert_eq!(day_of("2026-08"), None);
assert_eq!(day_of("20260820T00:00:00Z"), None);
assert_eq!(day_of("not-a-date"), None);
assert_eq!(day_of("2026-13-01"), None);
assert_eq!(day_of("2026-00-01"), None);
assert_eq!(day_of("2026-08-32"), None);
}
#[test]
fn a_week_starts_on_monday() {
assert_eq!(iso(week_start(day_of("2026-08-20").unwrap())), "2026-08-17");
assert_eq!(iso(week_start(day_of("2026-08-17").unwrap())), "2026-08-17");
assert_eq!(iso(week_start(day_of("2026-08-23").unwrap())), "2026-08-17");
assert_eq!(iso(week_start(day_of("2026-08-24").unwrap())), "2026-08-24");
}
#[test]
fn a_pre_epoch_day_still_lands_on_a_monday() {
for day in -400..400 {
let start = week_start(day);
assert!(start <= day && day - start < 7, "day {day} → {start}");
assert_eq!(week_start(start), start, "week_start is idempotent");
}
}
}