time/interop/
utcdatetime_systemtime.rs

1use core::cmp::Ordering;
2use core::ops::Sub;
3use std::time::SystemTime;
4
5use crate::{Duration, UtcDateTime};
6
7impl Sub<SystemTime> for UtcDateTime {
8    type Output = Duration;
9
10    /// # Panics
11    ///
12    /// This may panic if an overflow occurs.
13    #[inline]
14    #[track_caller]
15    fn sub(self, rhs: SystemTime) -> Self::Output {
16        self - Self::from(rhs)
17    }
18}
19
20impl Sub<UtcDateTime> for SystemTime {
21    type Output = Duration;
22
23    /// # Panics
24    ///
25    /// This may panic if an overflow occurs.
26    #[inline]
27    #[track_caller]
28    fn sub(self, rhs: UtcDateTime) -> Self::Output {
29        UtcDateTime::from(self) - rhs
30    }
31}
32
33impl PartialEq<SystemTime> for UtcDateTime {
34    #[inline]
35    fn eq(&self, rhs: &SystemTime) -> bool {
36        self == &Self::from(*rhs)
37    }
38}
39
40impl PartialEq<UtcDateTime> for SystemTime {
41    #[inline]
42    fn eq(&self, rhs: &UtcDateTime) -> bool {
43        &UtcDateTime::from(*self) == rhs
44    }
45}
46
47impl PartialOrd<SystemTime> for UtcDateTime {
48    #[inline]
49    fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> {
50        self.partial_cmp(&Self::from(*other))
51    }
52}
53
54impl PartialOrd<UtcDateTime> for SystemTime {
55    #[inline]
56    fn partial_cmp(&self, other: &UtcDateTime) -> Option<Ordering> {
57        UtcDateTime::from(*self).partial_cmp(other)
58    }
59}
60
61impl From<SystemTime> for UtcDateTime {
62    #[inline]
63    fn from(system_time: SystemTime) -> Self {
64        match system_time.duration_since(SystemTime::UNIX_EPOCH) {
65            Ok(duration) => Self::UNIX_EPOCH + duration,
66            Err(err) => Self::UNIX_EPOCH - err.duration(),
67        }
68    }
69}
70
71impl From<UtcDateTime> for SystemTime {
72    #[inline]
73    fn from(datetime: UtcDateTime) -> Self {
74        let duration = datetime - UtcDateTime::UNIX_EPOCH;
75
76        if duration.is_zero() {
77            Self::UNIX_EPOCH
78        } else if duration.is_positive() {
79            Self::UNIX_EPOCH + duration.unsigned_abs()
80        } else {
81            debug_assert!(duration.is_negative());
82            Self::UNIX_EPOCH - duration.unsigned_abs()
83        }
84    }
85}