display_more/
display_unix_epoch.rs1use std::fmt;
16use std::time::Duration;
17use std::time::UNIX_EPOCH;
18
19use chrono::DateTime;
20use chrono::Utc;
21
22pub struct DisplayUnixTimeStamp {
23 duration: Option<Duration>,
25
26 in_millis: bool,
27
28 with_timezone: bool,
29}
30
31impl fmt::Display for DisplayUnixTimeStamp {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 let duration = match self.duration {
34 Some(d) => d,
35 None => return write!(f, "None"),
36 };
37
38 let system_time = UNIX_EPOCH + duration;
39 let datetime: DateTime<Utc> = system_time.into();
40
41 let fmt = if self.in_millis {
42 if self.with_timezone {
43 "%Y-%m-%dT%H:%M:%S%.3fZ%z"
44 } else {
45 "%Y-%m-%dT%H:%M:%S%.3f"
46 }
47 } else if self.with_timezone {
48 "%Y-%m-%dT%H:%M:%S%.6fZ%z"
49 } else {
50 "%Y-%m-%dT%H:%M:%S%.6f"
51 };
52
53 write!(f, "{}", datetime.format(fmt))
54 }
55}
56
57impl DisplayUnixTimeStamp {
58 pub fn new(duration: Option<Duration>) -> Self {
59 Self {
60 duration,
61 in_millis: false,
62 with_timezone: true,
63 }
64 }
65
66 pub fn in_millis(self, in_millis: bool) -> Self {
67 Self { in_millis, ..self }
68 }
69
70 pub fn with_timezone(self, with_timezone: bool) -> Self {
71 Self {
72 with_timezone,
73 ..self
74 }
75 }
76}
77
78pub trait DisplayUnixTimeStampExt {
94 fn display_unix_timestamp(&self) -> DisplayUnixTimeStamp;
95
96 fn display_unix_timestamp_short(&self) -> DisplayUnixTimeStamp {
98 self.display_unix_timestamp()
99 .in_millis(true)
100 .with_timezone(false)
101 }
102}
103
104impl DisplayUnixTimeStampExt for Duration {
105 fn display_unix_timestamp(&self) -> DisplayUnixTimeStamp {
106 DisplayUnixTimeStamp::new(Some(*self))
107 }
108}
109
110impl DisplayUnixTimeStampExt for Option<Duration> {
111 fn display_unix_timestamp(&self) -> DisplayUnixTimeStamp {
112 DisplayUnixTimeStamp::new(*self)
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use std::time::Duration;
119
120 use super::*;
121
122 #[test]
123 fn test_display_unix_epoch() {
124 let epoch = Duration::from_millis(0);
125 let display = epoch.display_unix_timestamp();
126 assert_eq!(format!("{}", display), "1970-01-01T00:00:00.000000Z+0000");
127
128 let epoch = Duration::from_millis(1723102819023);
129 let display = epoch.display_unix_timestamp();
130 assert_eq!(format!("{}", display), "2024-08-08T07:40:19.023000Z+0000");
131
132 let display = epoch.display_unix_timestamp_short();
133 assert_eq!(format!("{}", display), "2024-08-08T07:40:19.023");
134
135 let some = Some(Duration::from_millis(1723102819023));
137 assert_eq!(
138 some.display_unix_timestamp().to_string(),
139 "2024-08-08T07:40:19.023000Z+0000"
140 );
141 assert_eq!(
142 some.display_unix_timestamp_short().to_string(),
143 "2024-08-08T07:40:19.023"
144 );
145
146 let none: Option<Duration> = None;
148 assert_eq!(none.display_unix_timestamp().to_string(), "None");
149 assert_eq!(none.display_unix_timestamp_short().to_string(), "None");
150 }
151}