Skip to main content

heatsync_core/
iso.rs

1//! the server's timestamps (`2026-10-04T20:00:00.000Z`) as unix seconds.
2
3/// only the shape the server sends; anything else is `None`.
4pub fn parse(s: &str) -> Option<i64> {
5    let b = s.as_bytes();
6    if b.len() < 19
7        || b[4] != b'-'
8        || b[7] != b'-'
9        || b[10] != b'T'
10        || b[13] != b':'
11        || b[16] != b':'
12    {
13        return None;
14    }
15    let n = |r: std::ops::Range<usize>| s.get(r)?.parse::<i64>().ok();
16    let (y, m, d) = (n(0..4)?, n(5..7)?, n(8..10)?);
17    let (hh, mm, ss) = (n(11..13)?, n(14..16)?, n(17..19)?);
18    if !(1..=12).contains(&m) || !(1..=31).contains(&d) {
19        return None;
20    }
21    // days from civil (Howard Hinnant)
22    let y = if m <= 2 { y - 1 } else { y };
23    let era = y.div_euclid(400);
24    let yoe = y - era * 400;
25    let doy = (153 * (if m > 2 { m - 3 } else { m + 9 }) + 2) / 5 + d - 1;
26    let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
27    let days = era * 146097 + doe - 719468;
28    Some(days * 86400 + hh * 3600 + mm * 60 + ss)
29}