kitsune_p2p_timestamp/
chrono_ext.rs1use super::*;
2use std::{convert::TryFrom, fmt, ops::Sub, str::FromStr};
3
4pub(crate) type DateTime = chrono::DateTime<chrono::Utc>;
5
6impl fmt::Display for Timestamp {
9 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10 let ce = -(62167219200 * MM)..=(253402214400 * MM);
11 if ce.contains(&self.0) {
12 if let Ok(ts) = chrono::DateTime::<chrono::Utc>::try_from(self) {
13 return write!(
14 f,
15 "{}",
16 ts.to_rfc3339_opts(chrono::SecondsFormat::AutoSi, true)
17 );
18 }
19 }
20 write!(f, "({}μs)", self.0)
23 }
24}
25
26impl fmt::Debug for Timestamp {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 write!(f, "Timestamp({})", self)
29 }
30}
31
32impl TryFrom<String> for Timestamp {
33 type Error = TimestampError;
34
35 fn try_from(t: String) -> Result<Self, Self::Error> {
36 Timestamp::from_str(t.as_ref())
37 }
38}
39
40impl TryFrom<&String> for Timestamp {
41 type Error = TimestampError;
42
43 fn try_from(t: &String) -> Result<Self, Self::Error> {
44 Timestamp::from_str(t.as_ref())
45 }
46}
47
48impl TryFrom<&str> for Timestamp {
49 type Error = TimestampError;
50
51 fn try_from(t: &str) -> Result<Self, Self::Error> {
52 Timestamp::from_str(t)
53 }
54}
55
56impl From<DateTime> for Timestamp {
57 fn from(t: DateTime) -> Self {
58 std::convert::From::from(&t)
59 }
60}
61
62impl From<&DateTime> for Timestamp {
63 fn from(t: &DateTime) -> Self {
64 let t = t.naive_utc().and_utc();
65 Timestamp(t.timestamp() * MM + t.timestamp_subsec_nanos() as i64 / 1000)
66 }
67}
68
69impl TryFrom<Timestamp> for DateTime {
74 type Error = TimestampError;
75
76 fn try_from(t: Timestamp) -> Result<Self, Self::Error> {
77 std::convert::TryFrom::try_from(&t)
78 }
79}
80
81impl TryFrom<&Timestamp> for DateTime {
82 type Error = TimestampError;
83
84 fn try_from(t: &Timestamp) -> Result<Self, Self::Error> {
85 let (secs, nsecs) = t.as_seconds_and_nanos();
86 chrono::DateTime::from_timestamp(secs, nsecs).ok_or(TimestampError::Overflow)
87 }
88}
89
90impl FromStr for Timestamp {
91 type Err = TimestampError;
92
93 fn from_str(t: &str) -> Result<Self, Self::Err> {
94 let t = chrono::DateTime::parse_from_rfc3339(t)?;
95 let t = chrono::DateTime::from_naive_utc_and_offset(t.naive_utc(), chrono::Utc);
96 Ok(t.into())
97 }
98}
99
100impl Timestamp {
101 #[cfg(feature = "now")]
106 pub fn now() -> Timestamp {
107 Timestamp::from(chrono::offset::Utc::now())
108 }
109 pub fn checked_difference_signed(&self, rhs: &Timestamp) -> Option<chrono::Duration> {
113 Some(chrono::Duration::microseconds(self.0.checked_sub(rhs.0)?))
114 }
115
116 pub fn checked_add_signed(&self, rhs: &chrono::Duration) -> Option<Timestamp> {
118 Some(Self(self.0.checked_add(rhs.num_microseconds()?)?))
119 }
120
121 pub fn checked_sub_signed(&self, rhs: &chrono::Duration) -> Option<Timestamp> {
123 self.checked_add_signed(&-*rhs)
124 }
125}
126impl Sub<Timestamp> for Timestamp {
130 type Output = TimestampResult<chrono::Duration>;
131
132 fn sub(self, rhs: Timestamp) -> Self::Output {
133 self.checked_difference_signed(&rhs)
134 .ok_or(TimestampError::Overflow)
135 }
136}