internationalization/
time.rs1use alloc::format;
2use alloc::string::String;
3
4pub fn format_unix_timestamp(unix_timestamp: i64, pattern: &str) -> String {
17 let (year, month, day, hour, minute, second) = shared::decompose_unix_timestamp(unix_timestamp);
18
19 let mut output = String::with_capacity(pattern.len() + 16);
20 let mut characters = pattern.chars();
21
22 while let Some(character) = characters.next() {
23 if character != '%' {
24 output.push(character);
25 continue;
26 }
27
28 match characters.next() {
29 Some('Y') => output.push_str(&format!("{:04}", year)),
30 Some('m') => output.push_str(&format!("{:02}", month)),
31 Some('d') => output.push_str(&format!("{:02}", day)),
32 Some('H') => output.push_str(&format!("{:02}", hour)),
33 Some('I') => output.push_str(&format!("{:02}", hour_12(hour))),
34 Some('M') => output.push_str(&format!("{:02}", minute)),
35 Some('S') => output.push_str(&format!("{:02}", second)),
36 Some('p') => output.push_str(if hour < 12 { "AM" } else { "PM" }),
37 Some('%') => output.push('%'),
38 Some(other) => {
39 output.push('%');
40 output.push(other);
41 }
42 None => output.push('%'),
43 }
44 }
45
46 output
47}
48
49const fn hour_12(hour_24: u8) -> u8 {
50 match hour_24 % 12 {
51 0 => 12,
52 value => value,
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn format_24_hour_time() {
62 let timestamp = 13 * 3600 + 5 * 60;
63 assert_eq!(format_unix_timestamp(timestamp, "%H:%M"), "13:05");
64 }
65
66 #[test]
67 fn format_12_hour_time_with_am_pm() {
68 let midnight = 0;
69 let afternoon = 13 * 3600 + 5 * 60;
70
71 assert_eq!(format_unix_timestamp(midnight, "%I:%M %p"), "12:00 AM");
72 assert_eq!(format_unix_timestamp(afternoon, "%I:%M %p"), "01:05 PM");
73 }
74
75 #[test]
76 fn format_date_and_time() {
77 assert_eq!(
78 format_unix_timestamp(0, "%Y-%m-%d %H:%M:%S"),
79 "1970-01-01 00:00:00"
80 );
81 }
82
83 #[test]
84 fn format_negative_unix_time() {
85 assert_eq!(
86 format_unix_timestamp(-1, "%Y-%m-%d %H:%M:%S"),
87 "1969-12-31 23:59:59"
88 );
89 }
90}