1use std::fmt::Debug;
7
8use sqlx::types::time::OffsetDateTime;
9
10#[derive(Clone)]
11pub struct Date {
12 pub time: OffsetDateTime,
13}
14
15impl Debug for Date {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 f.debug_struct("Date")
18 .field("time", &self.print_date())
19 .finish()
20 }
21}
22
23pub const MINUTE: i64 = 60;
24pub const HOUR: i64 = MINUTE * 60;
25pub const DAY: i64 = HOUR * 24;
26pub const WEEK: i64 = DAY * 7;
27
28impl Date {
29 pub fn format(date: &OffsetDateTime) -> String {
30 let timestamp = date.unix_timestamp();
31 let now = OffsetDateTime::now_utc().unix_timestamp();
32
33 let difference = now - timestamp;
34
35 if difference >= 3 * WEEK {
36 format!("{}{}{}", date.year(), date.month(), date.date())
37 } else if (DAY..(3 * WEEK)).contains(&difference) {
38 format!("{} days ago", date.hour())
39 } else if (HOUR..DAY).contains(&difference) {
40 format!("{} hours ago", date.hour())
41 } else if (MINUTE..HOUR).contains(&difference) {
42 format!("{} minutes ago", date.minute())
43 } else {
44 format!("{} seconds ago", date.second())
45 }
46 }
47
48 pub fn print_date(&self) -> String {
50 Self::format(&self.time)
51 }
52
53 pub fn date(&self) -> String {
55 format!(
56 "{}{}{}",
57 self.time.year(),
58 self.time.month(),
59 self.time.date()
60 )
61 }
62
63 pub fn new(unix: i64) -> Self {
64 Self {
65 time: OffsetDateTime::from_unix_timestamp(unix).unwrap(),
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn print_date_test() {
76 let mut n = Date {
77 time: OffsetDateTime::now_utc(),
78 };
79
80 let timestamp = n.time.unix_timestamp();
81 println!("timestamp: {}", timestamp);
82
83 assert!(n.print_date().contains("seconds ago"));
85 n.time = OffsetDateTime::from_unix_timestamp(timestamp - 5).unwrap();
86 assert!(n.print_date().contains("seconds ago"));
87
88 n.time = OffsetDateTime::from_unix_timestamp(timestamp - MINUTE * 2).unwrap();
90 assert!(n.print_date().contains("minutes ago"));
91 n.time = OffsetDateTime::from_unix_timestamp(timestamp - MINUTE * 56).unwrap();
92 assert!(n.print_date().contains("minutes ago"));
93
94 n.time = OffsetDateTime::from_unix_timestamp(timestamp - HOUR).unwrap();
96 assert!(n.print_date().contains("hours ago"));
97 n.time = OffsetDateTime::from_unix_timestamp(timestamp - HOUR * 23).unwrap();
98 assert!(n.print_date().contains("hours ago"));
99
100 n.time = OffsetDateTime::from_unix_timestamp(timestamp - 2 * WEEK).unwrap();
102 assert!(n.print_date().contains("days ago"));
103
104 n.time = OffsetDateTime::from_unix_timestamp(timestamp - 6 * WEEK).unwrap();
106 let date = format!("{}{}{}", n.time.year(), n.time.month(), n.time.date());
107 assert!(n.print_date().contains(&date))
108 }
109}