gnss_qc_traits/processing/time/
correction.rs

1use hifitime::{Duration, Epoch, Polynomial, TimeScale};
2
3/// [TimeCorrection] allows precise [Epoch] translation to another [TimeScale].
4/// For example, |[TimeScale::GPST]-[TimeScale::UTC]| when referencing [TimeScale::GPST] to [TimeScale::UTC].
5#[derive(Copy, Clone, PartialEq)]
6pub struct TimeCorrection {
7    /// LHS [TimeScale] to which [Polynomial] applies
8    pub lhs_timescale: TimeScale,
9
10    /// RHS [TimeScale] to which [Polynomial] applies
11    pub rhs_timescale: TimeScale,
12
13    /// Reference [Epoch] usually expressed in LHS [TimeScale], but we support any [TimeScale] here.
14    pub ref_epoch: Epoch,
15
16    /// Validity period as [Duration]
17    pub validity_period: Duration,
18
19    /// [Polynomial]
20    pub polynomial: Polynomial,
21}
22
23impl TimeCorrection {
24    /// Define new [TimeCorrection] from Reference [Epoch] expressed as week counter
25    /// and elapsed seconds within week.
26    pub fn from_reference_time_of_week_seconds(
27        ref_week: u32,
28        ref_tow: u64,
29        validity_period: Duration,
30        lhs_timescale: TimeScale,
31        rhs_timescale: TimeScale,
32        polynomial: Polynomial,
33    ) -> Self {
34        Self::from_reference_time_of_week_nanos(
35            ref_week,
36            ref_tow * 1_000_000_000,
37            validity_period,
38            lhs_timescale,
39            rhs_timescale,
40            polynomial,
41        )
42    }
43
44    /// Define new [TimeCorrection] from reference [Epoch] that must be expressed in the correct [TimeScale]
45    pub fn from_reference_epoch(
46        ref_epoch: Epoch,
47        validity_period: Duration,
48        rhs_timescale: TimeScale,
49        polynomial: Polynomial,
50    ) -> Self {
51        Self {
52            ref_epoch,
53            validity_period,
54            lhs_timescale: ref_epoch.time_scale,
55            rhs_timescale,
56            polynomial,
57        }
58    }
59
60    /// Define a new [TimeCorrections] from Reference [Epoch] expressed as week counter and
61    /// elapsed nanoseconds within week.
62    pub fn from_reference_time_of_week_nanos(
63        ref_week: u32,
64        ref_tow_nanos: u64,
65        validity_period: Duration,
66        lhs_timescale: TimeScale,
67        rhs_timescale: TimeScale,
68        polynomial: Polynomial,
69    ) -> Self {
70        let ref_epoch = Epoch::from_time_of_week(ref_week, ref_tow_nanos, lhs_timescale);
71
72        Self {
73            ref_epoch,
74            validity_period,
75            lhs_timescale,
76            rhs_timescale,
77            polynomial,
78        }
79    }
80
81    /// Returns true if this [TimeCorrection] should apply at ongoing [Epoch],
82    /// acoording to publication validity period.
83    pub fn applies(&self, now: Epoch) -> bool {
84        let dt = (now - self.ref_epoch).abs();
85        dt < self.validity_period
86    }
87
88    /// Returns first [Epoch] for which this [TimeCorrection] should apply.
89    pub fn validity_period_start(&self) -> Epoch {
90        self.ref_epoch - self.validity_period
91    }
92
93    /// Returns last [Epoch] for which this [TimeCorrection] should apply.
94    pub fn validity_period_end(&self) -> Epoch {
95        self.ref_epoch + self.validity_period
96    }
97}