1use std::time::Duration;
2
3#[allow(clippy::cast_possible_wrap)]
5pub fn format_system_time(duration: Duration) -> String {
6 let secs = duration.as_secs();
7 let millis = duration.subsec_millis();
8
9 let days_since_epoch = secs / 86400;
11 let time_of_day = secs % 86400;
12 let hours = time_of_day / 3600;
13 let minutes = (time_of_day % 3600) / 60;
14 let seconds = time_of_day % 60;
15
16 let (year, month, day) = days_to_date(days_since_epoch as i64);
18
19 format!("{year:04}-{month:02}-{day:02}T{hours:02}:{minutes:02}:{seconds:02}.{millis:03}Z")
20}
21
22#[allow(
25 clippy::cast_possible_wrap,
26 clippy::cast_sign_loss,
27 clippy::cast_possible_truncation,
28 clippy::missing_const_for_fn
29)]
30pub fn days_to_date(mut days: i64) -> (i64, u32, u32) {
31 days += 719_468;
32 let era = if days >= 0 { days } else { days - 146_096 } / 146_097;
33 let doe = (days - era * 146_097) as u32;
34 let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365;
35 #[allow(clippy::cast_lossless)]
36 let year = yoe as i64 + era * 400;
37 let day_of_year = doe - (365 * yoe + yoe / 4 - yoe / 100);
38 let mp = (5 * day_of_year + 2) / 153;
39 let day = day_of_year - (153 * mp + 2) / 5 + 1;
40 let month = if mp < 10 { mp + 3 } else { mp - 9 };
41 let year = if month <= 2 { year + 1 } else { year };
42 (year, month, day)
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_format_system_time() {
51 let duration = Duration::from_secs(0);
53 assert_eq!(format_system_time(duration), "1970-01-01T00:00:00.000Z");
54
55 let duration = Duration::from_secs(1_704_110_400);
57 assert_eq!(format_system_time(duration), "2024-01-01T12:00:00.000Z");
58 }
59
60 #[test]
61 fn test_days_to_date() {
62 assert_eq!(days_to_date(0), (1970, 1, 1));
64
65 assert_eq!(days_to_date(365), (1971, 1, 1));
67 assert_eq!(days_to_date(19723), (2024, 1, 1));
68 }
69}