1use std::time::Duration as StdDuration;
8
9use time::format_description::well_known::Rfc3339;
10use time::OffsetDateTime;
11
12pub(crate) fn format_timestamp_rfc3339(value: OffsetDateTime) -> String {
15 value.format(&Rfc3339).unwrap_or_else(|_| value.to_string())
16}
17
18pub(crate) fn format_unix_ms_rfc3339(ms: i64) -> String {
20 let seconds = ms.div_euclid(1000);
21 let value = OffsetDateTime::from_unix_timestamp(seconds).unwrap_or(OffsetDateTime::UNIX_EPOCH);
22 format_timestamp_rfc3339(value)
23}
24
25pub(crate) fn format_duration_coarse(value: StdDuration) -> String {
30 if value.as_secs() == 0 {
31 return format!("{}ms", value.as_millis());
32 }
33 let seconds = value.as_secs();
34 if seconds < 60 {
35 return format!("{seconds}s");
36 }
37 if seconds < 60 * 60 {
38 return format!("{}m", seconds / 60);
39 }
40 if seconds < 60 * 60 * 24 {
41 return format!("{}h", seconds / (60 * 60));
42 }
43 format!("{}d", seconds / (60 * 60 * 24))
44}
45
46pub(crate) fn format_duration_ms(duration_ms: u64) -> String {
49 if duration_ms >= 60_000 {
50 format!("{:.1}m", duration_ms as f64 / 60_000.0)
51 } else if duration_ms >= 1_000 {
52 format!("{:.1}s", duration_ms as f64 / 1_000.0)
53 } else {
54 format!("{duration_ms}ms")
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn timestamp_uses_rfc3339() {
64 let value = OffsetDateTime::UNIX_EPOCH;
65 assert_eq!(format_timestamp_rfc3339(value), "1970-01-01T00:00:00Z");
66 }
67
68 #[test]
69 fn unix_ms_rounds_to_seconds() {
70 assert_eq!(format_unix_ms_rfc3339(0), "1970-01-01T00:00:00Z");
71 assert_eq!(format_unix_ms_rfc3339(1500), "1970-01-01T00:00:01Z");
72 assert_eq!(format_unix_ms_rfc3339(-1), "1969-12-31T23:59:59Z");
74 }
75
76 #[test]
77 fn coarse_duration_picks_a_unit() {
78 assert_eq!(format_duration_coarse(StdDuration::from_millis(0)), "0ms");
79 assert_eq!(format_duration_coarse(StdDuration::from_secs(5)), "5s");
80 assert_eq!(format_duration_coarse(StdDuration::from_secs(120)), "2m");
81 assert_eq!(format_duration_coarse(StdDuration::from_secs(7200)), "2h");
82 assert_eq!(
83 format_duration_coarse(StdDuration::from_secs(86_400 * 3)),
84 "3d"
85 );
86 }
87
88 #[test]
89 fn ms_duration_uses_one_decimal_above_a_second() {
90 assert_eq!(format_duration_ms(500), "500ms");
91 assert_eq!(format_duration_ms(1_500), "1.5s");
92 assert_eq!(format_duration_ms(90_000), "1.5m");
93 }
94}