use crate::{PosixNs, RenderZone};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LocalResolution {
Unique(PosixNs),
Fold {
earlier: PosixNs,
later: PosixNs,
},
Gap,
}
#[must_use]
pub fn resolve_local(naive: PosixNs, zone: &RenderZone) -> LocalResolution {
let tz = match zone {
RenderZone::Utc => return LocalResolution::Unique(naive),
RenderZone::Fixed(offset) => offset.to_time_zone(),
RenderZone::Named(tz) => tz.clone(),
};
let Ok(ts) = jiff::Timestamp::from_nanosecond(naive.0) else {
return LocalResolution::Unique(naive);
};
let civil = jiff::tz::Offset::UTC.to_datetime(ts);
let amb = tz.to_ambiguous_timestamp(civil);
match amb.offset() {
jiff::tz::AmbiguousOffset::Unambiguous { .. } => amb
.unambiguous()
.map_or(LocalResolution::Unique(naive), |t| {
LocalResolution::Unique(PosixNs(t.as_nanosecond()))
}),
jiff::tz::AmbiguousOffset::Gap { .. } => LocalResolution::Gap,
jiff::tz::AmbiguousOffset::Fold { .. } => match (amb.earlier(), amb.later()) {
(Ok(e), Ok(l)) => LocalResolution::Fold {
earlier: PosixNs(e.as_nanosecond()),
later: PosixNs(l.as_nanosecond()),
},
_ => LocalResolution::Unique(naive),
},
}
}