| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- //! UTC timestamps without a chrono dependency: Howard Hinnant's
- //! civil_from_days for the calendar math, unix-epoch seconds everywhere
- //! else (the run ledger stores epochs and renders through [`fmt_ts`]).
- use std::time::{SystemTime, UNIX_EPOCH};
- /// Unix-epoch seconds right now (UTC).
- pub(crate) fn now_secs() -> i64 {
- SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map(|d| d.as_secs() as i64)
- .unwrap_or(0)
- }
- /// `YYYY-MM-DD_HHMMSS` in UTC (bench report file names).
- pub(crate) fn utc_stamp() -> String {
- let secs = now_secs();
- let (h, m, s) = ((secs % 86400) / 3600, (secs % 3600) / 60, secs % 60);
- let (y, mo, d) = civil_date(secs / 86400);
- format!(
- "{y:04}-{mo:02}-{d:02}_{h:02}{m:02}{s:02}",
- y = y,
- mo = mo,
- d = d
- )
- }
- /// `YYYY-MM-DD HH:MM` in UTC (run-ledger display).
- pub(crate) fn fmt_ts(secs: i64) -> String {
- let (h, m, _) = ((secs % 86400) / 3600, (secs % 3600) / 60, secs % 60);
- let (y, mo, d) = civil_date(secs / 86400);
- format!("{y:04}-{mo:02}-{d:02} {h:02}:{m:02}")
- }
- /// Days since 1970-01-01 → (year, month, day); Howard Hinnant's civil_from_days.
- pub(crate) fn civil_date(z: i64) -> (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 / 1_460 + doe / 36_524 - 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 mo = if mp < 10 { mp + 3 } else { mp - 9 };
- let y = if mo <= 2 { y + 1 } else { y };
- (y, mo, d)
- }
- #[cfg(test)]
- mod tests {
- use super::*;
- #[test]
- fn stamp_format() {
- let s = utc_stamp();
- assert_eq!(s.len(), 17, "{s}");
- assert_eq!(&s[4..5], "-");
- assert_eq!(&s[7..8], "-");
- assert_eq!(&s[10..11], "_");
- }
- #[test]
- fn civil_date_known_values() {
- assert_eq!(civil_date(0), (1970, 1, 1));
- assert_eq!(civil_date(19_723), (2024, 1, 1));
- assert_eq!(civil_date(20_818), (2026, 12, 31));
- }
- #[test]
- fn fmt_ts_renders_date_and_minute() {
- // 2026-09-14 10:03:00 UTC
- assert_eq!(fmt_ts(1_789_380_180), "2026-09-14 10:03");
- }
- }
|