ezk_rtp/
ntp_timestamp.rs

1use std::ops::Sub;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
4pub struct NtpTimestamp {
5    // Duration since 01.01.1900
6    inner: time::Duration,
7}
8
9impl NtpTimestamp {
10    pub const ZERO: Self = Self {
11        inner: time::Duration::ZERO,
12    };
13
14    pub fn now() -> Self {
15        let epoch = time::Date::from_calendar_date(1900, time::Month::January, 1).unwrap();
16        let epoch = time::OffsetDateTime::new_utc(epoch, time::Time::MIDNIGHT);
17
18        Self {
19            inner: time::OffsetDateTime::now_utc() - epoch,
20        }
21    }
22
23    pub fn as_seconds_f64(self) -> f64 {
24        self.inner.as_seconds_f64()
25    }
26
27    pub fn to_fixed_u64(self) -> u64 {
28        let seconds = self.inner.whole_seconds() as u64;
29        let subseconds =
30            (self.inner.subsec_nanoseconds() as f64 / 1_000_000_000.) * u32::MAX as f64;
31        let subseconds = subseconds as u64;
32
33        (seconds << 32) | subseconds
34    }
35
36    pub fn to_fixed_u32(self) -> u32 {
37        ((self.to_fixed_u64() >> 16) & u64::from(u32::MAX)) as u32
38    }
39
40    pub fn from_fixed_u64(fixed: u64) -> Self {
41        let seconds = (fixed >> 32) as i64;
42
43        let subseconds = (fixed & u64::from(u32::MAX)) as u32;
44        let subseconds = subseconds as f64 / (u32::MAX as f64);
45
46        Self {
47            inner: time::Duration::new(seconds, (subseconds * 1_000_000_000.) as i32),
48        }
49    }
50
51    pub fn from_fixed_u32(fixed: u32) -> Self {
52        let seconds = (fixed >> 16) as i64;
53
54        let subseconds = (fixed & u32::from(u16::MAX)) as u16;
55        let subseconds = subseconds as f64 / (u16::MAX as f64);
56
57        Self {
58            inner: time::Duration::new(seconds, (subseconds * 1_000_000_000.) as i32),
59        }
60    }
61}
62
63impl Sub for NtpTimestamp {
64    type Output = time::Duration;
65
66    fn sub(self, rhs: Self) -> Self::Output {
67        self.inner - rhs.inner
68    }
69}