use std::time::SystemTime;
pub trait SystemTimeExt: sealed::Sealed {
#[cfg(any(feature = "fmt", test))]
fn display_iso_8601(&self) -> impl std::fmt::Display;
}
impl SystemTimeExt for SystemTime {
#[cfg(any(feature = "fmt", test))]
fn display_iso_8601(&self) -> impl std::fmt::Display {
to_timestamp(*self)
}
}
#[cfg(any(feature = "fmt", test))]
fn to_timestamp(system_time: SystemTime) -> jiff::Timestamp {
match jiff::Timestamp::try_from(system_time) {
Ok(timestamp) => timestamp,
Err(_) => to_timestamp_min_max(system_time),
}
}
#[cfg(any(feature = "fmt", test))]
fn to_timestamp_min_max(system_time: SystemTime) -> jiff::Timestamp {
if system_time.duration_since(SystemTime::UNIX_EPOCH).is_ok() {
jiff::Timestamp::MAX
} else {
jiff::Timestamp::MIN
}
}
mod sealed {
pub trait Sealed {}
impl Sealed for std::time::SystemTime {}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use std::time::Duration;
use jiff::Timestamp;
use super::*;
#[test]
fn display_ok() {
assert_eq!(SystemTime::UNIX_EPOCH.display_iso_8601().to_string(), "1970-01-01T00:00:00Z");
assert_eq!(
(SystemTime::UNIX_EPOCH + Duration::from_hours(1)).display_iso_8601().to_string(),
"1970-01-01T01:00:00Z"
);
}
#[test]
fn display_out_of_range() {
let time = SystemTime::from(Timestamp::MAX) + Duration::from_secs(12345);
assert_eq!(time.display_iso_8601().to_string(), "9999-12-30T22:00:00.999999999Z");
}
#[test]
fn to_timestamp_fallback_ok() {
let now = SystemTime::UNIX_EPOCH + Duration::from_secs(12345);
assert_eq!(to_timestamp_min_max(now), jiff::Timestamp::MAX);
let past = SystemTime::UNIX_EPOCH - Duration::from_secs(12345);
assert_eq!(to_timestamp_min_max(past), jiff::Timestamp::MIN);
}
}