rtc_shared/
time.rs

1use std::ops::Add;
2use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
3
4#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5pub struct SystemInstant {
6    instant: Instant,
7    duration_since_unix_epoch: Duration,
8}
9
10impl SystemInstant {
11    pub fn now() -> Self {
12        Self {
13            instant: Instant::now(),
14            duration_since_unix_epoch: SystemTime::now()
15                .duration_since(UNIX_EPOCH)
16                .unwrap_or_else(|_| Duration::from_secs(0)),
17        }
18    }
19
20    pub fn instant(&self, duration_since_unix_epoch: Duration) -> Instant {
21        self.instant + duration_since_unix_epoch - self.duration_since_unix_epoch
22    }
23
24    pub fn duration_since_unix_epoch(&self) -> Duration {
25        self.duration_since_unix_epoch
26    }
27
28    pub fn unix(&self, now: Instant) -> Duration {
29        now.duration_since(self.instant)
30            .add(self.duration_since_unix_epoch)
31    }
32
33    pub fn ntp(&self, now: Instant) -> u64 {
34        SystemInstant::unix2ntp(self.unix(now))
35    }
36
37    pub fn unix2ntp(duration_since_unix_epoch: Duration) -> u64 {
38        let u = duration_since_unix_epoch.as_nanos() as u64;
39
40        let mut s = u / 1_000_000_000;
41        s += 0x83AA7E80; //offset in seconds between unix epoch and ntp epoch
42        let mut f = u % 1_000_000_000;
43        f <<= 32;
44        f /= 1_000_000_000;
45        s <<= 32;
46
47        s | f
48    }
49
50    pub fn ntp2unix(ntp: u64) -> Duration {
51        let mut s = ntp >> 32;
52        let mut f = ntp & 0xFFFFFFFF;
53        f *= 1_000_000_000;
54        f >>= 32;
55        s -= 0x83AA7E80;
56        let u = s * 1_000_000_000 + f;
57
58        /*let duration_since_unix_epoch =*/
59        Duration::new(u / 1_000_000_000, (u % 1_000_000_000) as u32)
60    }
61}