1use serde::{Deserialize, Serialize};
2
3#[derive(
4 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize,
5)]
6#[serde(transparent)]
7pub struct Timestamp(pub i64);
8
9impl Timestamp {
10 pub fn now() -> Self {
11 Self(chrono::Utc::now().timestamp_millis())
12 }
13
14 pub fn as_millis(&self) -> i64 {
15 self.0
16 }
17
18 pub fn to_datetime(&self) -> chrono::DateTime<chrono::Utc> {
19 chrono::DateTime::from_timestamp_millis(self.0)
20 .unwrap_or_default()
21 .with_timezone(&chrono::Utc)
22 }
23}
24
25impl From<i64> for Timestamp {
26 fn from(value: i64) -> Self {
27 Self(value)
28 }
29}
30
31impl From<u64> for Timestamp {
32 fn from(value: u64) -> Self {
33 Self(value as i64)
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn test_timestamp_conversions() {
43 let ts = Timestamp::from(1000i64);
44 assert_eq!(ts.as_millis(), 1000);
45 let dt = ts.to_datetime();
46 assert_eq!(dt.timestamp_millis(), 1000);
47
48 let ts2 = Timestamp::from(2000u64);
49 assert_eq!(ts2.as_millis(), 2000);
50 }
51
52 #[test]
53 fn test_timestamp_now() {
54 let before = chrono::Utc::now().timestamp_millis();
55 let ts = Timestamp::now();
56 let after = chrono::Utc::now().timestamp_millis();
57 assert!(ts.as_millis() >= before);
58 assert!(ts.as_millis() <= after);
59 }
60}