#![forbid(unsafe_code)]
use crate::civil::civil_from_days;
use crate::tzif::LeapSecond;
pub fn corr_at(leaps: &[LeapSecond], t: i64) -> i32 {
let mut c = 0;
for l in leaps {
if l.occur <= t {
c = l.corr;
} else {
break;
}
}
c
}
pub fn displayed_leap(occur: i64, corr: i32) -> String {
let t = occur - corr as i64;
let days = t.div_euclid(86400);
let secs = t.rem_euclid(86400);
let (y, m, d) = civil_from_days(days);
let (hh, mm, ss) = (secs / 3600, (secs % 3600) / 60, secs % 60);
let shown = if ss == 59 { 60 } else { ss };
format!("{y:04}-{m:02}-{d:02}T{hh:02}:{mm:02}:{shown:02}Z")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn first_two_leaps_render_60() {
assert_eq!(displayed_leap(78796800, 1), "1972-06-30T23:59:60Z");
assert_eq!(displayed_leap(94694401, 2), "1972-12-31T23:59:60Z");
assert_eq!(displayed_leap(126230402, 3), "1973-12-31T23:59:60Z");
}
#[test]
fn corr_lookup_is_monotone() {
let leaps = vec![
LeapSecond {
occur: 78796800,
corr: 1,
},
LeapSecond {
occur: 94694401,
corr: 2,
},
];
assert_eq!(corr_at(&leaps, 0), 0);
assert_eq!(corr_at(&leaps, 78796800), 1);
assert_eq!(corr_at(&leaps, 94694401), 2);
assert_eq!(corr_at(&leaps, 99999999999), 2);
}
}