1use chrono::NaiveDateTime;
2
3pub fn timestamp(bytes: &[u8; 16]) -> Option<NaiveDateTime> {
5 let version_num = bytes[6] >> 4;
7
8 match version_num {
10 7 => {
12 let millis = u64::from_be_bytes([
13 0, 0, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5],
14 ]);
15
16 Some(
17 NaiveDateTime::from_timestamp_millis(millis as i64)
18 .expect("invalid or out-of-range datetime"),
19 )
20 }
21 _ => None,
22 }
23}
24
25#[cfg(test)]
26mod tests {
27 use super::*;
28
29 use chrono::Utc;
30
31 #[test]
32 fn test_for_crate_uuid7() {
33 let v = "0184e596-ec2c-77a8-b4a9-9be4d1dcdb47"
35 .parse::<uuid7::Uuid>()
36 .unwrap();
37 assert!(timestamp(v.as_bytes()).is_some());
38
39 let dt_start = Utc::now().naive_utc();
41 let dt = timestamp(uuid7::uuid7().as_bytes()).unwrap();
42 let dt_end = Utc::now().naive_utc();
43 assert!(dt_start.timestamp_millis() <= dt.timestamp_millis());
44 assert!(dt.timestamp_millis() <= dt_end.timestamp_millis());
45 }
46
47 #[cfg(uuid_unstable)]
48 #[test]
49 fn test_for_crate_uuid_v7() {
50 let v = "0184e596-ec2c-77a8-b4a9-9be4d1dcdb47"
52 .parse::<uuid::Uuid>()
53 .unwrap();
54 assert!(timestamp(v.as_bytes()).is_some());
55
56 let dt_start = Utc::now().naive_utc();
58 let dt = timestamp(uuid::Uuid::now_v7().as_bytes()).unwrap();
59 let dt_end = Utc::now().naive_utc();
60 assert!(dt_start.timestamp_millis() <= dt.timestamp_millis());
61 assert!(dt.timestamp_millis() <= dt_end.timestamp_millis());
62 }
63}