1#[cfg(not(target_arch = "wasm32"))]
6use std::time::{SystemTime, UNIX_EPOCH};
7#[cfg(target_arch = "wasm32")]
8use web_time::{SystemTime, UNIX_EPOCH};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
13pub struct UnixMillis(pub u64);
14
15impl UnixMillis {
16 pub fn now() -> Self {
19 Self::at(SystemTime::now()) }
21
22 fn at(time: SystemTime) -> Self {
23 Self(time.duration_since(UNIX_EPOCH).map_or(0, |since| {
24 u64::try_from(since.as_millis()).unwrap_or(u64::MAX)
25 }))
26 }
27}
28
29#[cfg(test)]
30mod tests {
31 use std::time::Duration;
32
33 use super::*;
34
35 #[test]
36 fn now_is_after_2026_and_never_runs_backwards_between_two_calls() {
37 let first = UnixMillis::now();
39 assert!(first > UnixMillis(1_767_225_600_000), "{first:?}");
40 let second = UnixMillis::now();
41 assert!(second >= first, "{second:?} < {first:?}");
42 }
43
44 #[test]
45 fn a_clock_before_1970_reads_zero() {
46 assert_eq!(
47 UnixMillis::at(UNIX_EPOCH - Duration::from_secs(1)),
48 UnixMillis(0)
49 );
50 assert_eq!(
51 UnixMillis::at(UNIX_EPOCH + Duration::from_millis(1_500)),
52 UnixMillis(1_500)
53 );
54 }
55}