Skip to main content

deep_time/dt/
hifitime.rs

1use crate::{Dt, Scale};
2use core::convert::From;
3use hifitime::{Duration, Epoch};
4
5impl Dt {
6    /// Converts this [`Dt`] to a [`hifitime::Epoch`].
7    ///
8    /// - The [`Dt`] is first converted to `Scale::TAI` before producing a result.
9    /// - The returned [`hifitime::Epoch`] is on the TAI time scale.
10    pub fn to_hifitime_epoch(&self) -> Epoch {
11        let nanos = self.to_tai().to_ns().0;
12
13        // [`Dt::ZERO`] is J2000.0 TAI noon; anchor on hifitime's matching instant.
14        let j2000 = Epoch::from_gregorian_tai(2000, 1, 1, 12, 0, 0, 0);
15        let ns_since_j1900 = nanos.saturating_add(j2000.to_tai_duration().total_nanoseconds());
16
17        Epoch::from_tai_duration(Duration::from_total_nanoseconds(ns_since_j1900))
18    }
19
20    /// Creates a TAI [`Dt`] from a [`hifitime::Epoch`].
21    pub fn from_hifitime_epoch(epoch: Epoch) -> Dt {
22        let ns_since_j1900 = epoch.to_tai_duration().total_nanoseconds();
23
24        let j2000 = Epoch::from_gregorian_tai(2000, 1, 1, 12, 0, 0, 0);
25        let ns_since_zero_tai =
26            ns_since_j1900.saturating_sub(j2000.to_tai_duration().total_nanoseconds());
27        Self::from_ns(ns_since_zero_tai, 0, Scale::TAI, Scale::TAI)
28    }
29
30    /// Converts this [`Dt`] to a [`hifitime::Duration`] (nanosecond precision).
31    ///
32    /// - Sub-nanosecond attoseconds are **truncated toward zero**.
33    /// - The conversion is exact up to the nanosecond (128-bit integer arithmetic).
34    /// - Internally uses [`hifitime::Duration::from_total_nanoseconds`], which
35    ///   automatically normalizes centuries/nanoseconds and saturates at
36    ///   [`Duration::MAX`] / [`Duration::MIN`] if outside hifitime's range
37    ///   (±32,768 centuries).
38    #[inline(always)]
39    pub fn to_hifitime_duration(&self) -> Duration {
40        Duration::from_total_nanoseconds(self.to_ns().0)
41    }
42
43    /// Creates a [`Dt`] from a [`hifitime::Duration`] (nanosecond precision).
44    ///
45    /// Inverse of [`Dt::to_hifitime_duration`].
46    #[inline(always)]
47    pub fn from_hifitime_duration(dur: Duration) -> Dt {
48        Self::from_ns(dur.total_nanoseconds(), 0, Scale::TAI, Scale::TAI)
49    }
50}
51
52impl From<Epoch> for Dt {
53    #[inline]
54    fn from(epoch: Epoch) -> Self {
55        Self::from_hifitime_epoch(epoch)
56    }
57}
58
59impl From<Dt> for Epoch {
60    #[inline]
61    fn from(dt: Dt) -> Self {
62        dt.to_hifitime_epoch()
63    }
64}
65
66impl From<Duration> for Dt {
67    #[inline]
68    fn from(dur: Duration) -> Self {
69        Self::from_hifitime_duration(dur)
70    }
71}
72
73impl From<Dt> for Duration {
74    #[inline]
75    fn from(dt: Dt) -> Self {
76        dt.to_hifitime_duration()
77    }
78}