monetize-embed 0.1.1

The thin client a monetized product compiles in: an Ed25519-verified entitlement cache with nanosecond verdicts that keeps answering while the licence server is unreachable. No network, no ledger — the product feeds it signed facts and asks.
Documentation
//! Proleptic Gregorian civil dates from unix milliseconds, pure integer arithmetic
//! (Howard Hinnant's `days_from_civil` / `civil_from_days`). Here rather than in core
//! because both sides need it: core to compute a period's end and a reference's date
//! label, embed to print `plan expired 2026-10-01` in a refusal line. No chrono: the
//! product should not inherit a date library for one string.

pub const DAY_MS: u64 = 86_400_000;

/// `(year, month, day)` of the UTC day containing `unix_ms`.
pub fn civil_from_unix_ms(unix_ms: u64) -> (i64, u32, u32) {
    let z = (unix_ms / DAY_MS) as i64 + 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 / 36_524 - doe / 146_096) / 365;
    let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
    let mp = (5 * doy + 2) / 153;
    let d = (doy - (153 * mp + 2) / 5 + 1) as u32;
    let m = if mp < 10 { mp + 3 } else { mp - 9 } as u32;
    let y = yoe + era * 400 + if m <= 2 { 1 } else { 0 };
    (y, m, d)
}

/// Midnight UTC of `y-m-d` in unix milliseconds. Dates before 1970 saturate to 0.
pub fn unix_ms_from_civil(y: i64, m: u32, d: u32) -> u64 {
    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 = if m > 2 { m - 3 } else { m + 9 } as i64;
    let doy = (153 * mp + 2) / 5 + d as i64 - 1;
    let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
    let days = era * 146_097 + doe - 719_468;
    if days < 0 { 0 } else { days as u64 * DAY_MS }
}

pub fn days_in_month(y: i64, m: u32) -> u32 {
    match m {
        1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
        4 | 6 | 9 | 11 => 30,
        _ => {
            if (y % 4 == 0 && y % 100 != 0) || y % 400 == 0 { 29 } else { 28 }
        }
    }
}

/// `YYYY-MM-DD` of the UTC day containing `unix_ms`.
pub fn iso_date(unix_ms: u64) -> String {
    let (y, m, d) = civil_from_unix_ms(unix_ms);
    format!("{y:04}-{m:02}-{d:02}")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn round_trips_known_dates() {
        for (y, m, d) in [(1970, 1, 1), (2000, 2, 29), (2026, 9, 3), (2100, 12, 31)] {
            let ms = unix_ms_from_civil(y, m, d);
            assert_eq!(civil_from_unix_ms(ms), (y, m, d));
            assert_eq!(civil_from_unix_ms(ms + DAY_MS - 1), (y, m, d), "end of day stays");
        }
        assert_eq!(iso_date(unix_ms_from_civil(2026, 9, 3)), "2026-09-03");
    }

    #[test]
    fn refuse_twin_the_day_after_is_not_the_same_day() {
        let ms = unix_ms_from_civil(2026, 9, 3);
        assert_ne!(civil_from_unix_ms(ms + DAY_MS), (2026, 9, 3));
        assert_eq!(iso_date(ms + DAY_MS), "2026-09-04");
        assert_eq!(days_in_month(2024, 2), 29);
        assert_eq!(days_in_month(1900, 2), 28);
    }
}