use std::time::{SystemTime, UNIX_EPOCH}; pub fn unix_seconds() -> i64 { SystemTime::now() .duration_since(UNIX_EPOCH) .map(|elapsed| elapsed.as_secs() as i64) .unwrap_or_default() } pub fn unix_millis() -> i64 { SystemTime::now() .duration_since(UNIX_EPOCH) .map(|elapsed| elapsed.as_millis() as i64) .unwrap_or_default() } pub fn format_utc(seconds: i64) -> String { let days_since_epoch = seconds.div_euclid(86_400); let seconds_of_day = seconds.rem_euclid(86_400); let (year, month, day) = civil_from_days(days_since_epoch); format!( "{year:04}-{month:02}-{day:02}T{:02}:{:02}:{:02}Z", seconds_of_day / 3_600, (seconds_of_day % 3_600) / 60, seconds_of_day % 60 ) } fn civil_from_days(days: i64) -> (i64, u32, u32) { let z = days + 719_468; let era = z.div_euclid(146_097); let day_of_era = z.rem_euclid(146_097); let year_of_era = (day_of_era - day_of_era / 1_460 + day_of_era / 36_524 - day_of_era / 146_096) / 365; let year = year_of_era + era * 400; let day_of_year = day_of_era - (365 * year_of_era + year_of_era / 4 - year_of_era / 100); let shifted_month = (5 * day_of_year + 2) / 153; let day = (day_of_year - (153 * shifted_month + 2) / 5 + 1) as u32; let month = if shifted_month < 10 { shifted_month + 3 } else { shifted_month - 9 } as u32; (year + i64::from(month <= 2), month, day) } pub fn days_between(from_seconds: i64, to_seconds: i64) -> i32 { ((to_seconds - from_seconds).max(0) / 86_400) as i32 }