1pub fn now_epoch() -> i64 {
3 std::time::SystemTime::now()
4 .duration_since(std::time::UNIX_EPOCH)
5 .unwrap_or(std::time::Duration::ZERO)
6 .as_secs() as i64
7}
8
9pub fn format_age(timestamp: i64) -> String {
11 let age = now_epoch() - timestamp;
12 if age < 60 {
13 format!("{age}s ago")
14 } else if age < 3600 {
15 format!("{}min ago", age / 60)
16 } else if age < 86400 {
17 format!("{}h ago", age / 3600)
18 } else {
19 format!("{}d ago", age / 86400)
20 }
21}
22
23#[cfg(test)]
24mod tests {
25 use super::*;
26
27 #[test]
28 fn test_format_age_seconds() {
29 let ts = now_epoch() - 30;
33 assert!(
34 format_age(ts).ends_with("s ago"),
35 "expected 's ago' suffix for 30s"
36 );
37 }
38
39 #[test]
40 fn test_format_age_minutes() {
41 let ts = now_epoch() - 120;
43 assert!(
44 format_age(ts).ends_with("min ago"),
45 "expected 'min ago' suffix for 120s"
46 );
47 }
48
49 #[test]
50 fn test_format_age_hours() {
51 let ts = now_epoch() - 7200;
53 assert!(
54 format_age(ts).ends_with("h ago"),
55 "expected 'h ago' suffix for 7200s"
56 );
57 }
58
59 #[test]
60 fn test_format_age_days() {
61 let ts = now_epoch() - 172_800;
63 assert!(
64 format_age(ts).ends_with("d ago"),
65 "expected 'd ago' suffix for 172800s"
66 );
67 }
68}