pub fn unix_timestamp(yy: u8, month: u8, day: u8, hour: u8, minute: u8, second: u8) -> i64 {
let days = days_from_civil(2000 + yy as i64, month as u32, day as u32);
days * 86_400 + hour as i64 * 3600 + minute as i64 * 60 + second as i64
}
fn days_from_civil(y: i64, m: u32, d: u32) -> i64 {
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 m = m as i64;
let d = d as i64;
let doy = (153 * (if m > 2 { m - 3 } else { m + 9 }) + 2) / 5 + d - 1; let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; era * 146_097 + doe - 719_468
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn matches_reference_fix_time() {
assert_eq!(unix_timestamp(24, 6, 15, 10, 30, 45), 1718447445);
}
#[test]
fn epoch_start() {
assert_eq!(unix_timestamp(0, 1, 1, 0, 0, 0), 946_684_800);
}
#[test]
fn leap_day() {
assert_eq!(unix_timestamp(24, 2, 29, 0, 0, 0), 1_709_164_800);
}
#[test]
fn year_end_rollover() {
assert_eq!(unix_timestamp(23, 12, 31, 23, 59, 59), 1_704_067_199);
}
}