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 display = epoch.display_unix_timestamp().in_millis(true);
136 assert_eq!(format!("{}", display), "2024-08-08T07:40:19.023Z+0000");
137
138 let display = epoch.display_unix_timestamp().with_timezone(false);
139 assert_eq!(format!("{}", display), "2024-08-08T07:40:19.023000");
140
141 let some = Some(Duration::from_millis(1723102819023));
143 assert_eq!(
144 some.display_unix_timestamp().to_string(),
145 "2024-08-08T07:40:19.023000Z+0000"
146 );
147 assert_eq!(
148 some.display_unix_timestamp_short().to_string(),
149 "2024-08-08T07:40:19.023"
150 );
151
152 let none: Option<Duration> = None;
154 assert_eq!(none.display_unix_timestamp().to_string(), "None");
155 assert_eq!(none.display_unix_timestamp_short().to_string(), "None");
156 }
157}