tempoch_core/features/
time_instant.rs1use qtty::Day;
7
8use crate::format::{JulianDate, ModifiedJulianDate};
9use crate::format::{JD, MJD};
10use crate::model::scale::CoordinateScale;
11use crate::model::scale::TT;
12use crate::model::time::Time;
13use crate::InfallibleFormatForScale;
14use qtty::Second;
15
16pub trait TimeInstant: Copy + PartialOrd {
20 type Duration;
22
23 fn difference(&self, other: &Self) -> Self::Duration;
25
26 fn add_duration(&self, duration: Self::Duration) -> Self;
28}
29
30impl TimeInstant for Time<TT> {
31 type Duration = Second;
32
33 #[inline]
34 fn difference(&self, other: &Self) -> Second {
35 *self - *other
36 }
37
38 #[inline]
39 fn add_duration(&self, dur: Second) -> Self {
40 *self + dur
41 }
42}
43
44impl<S: CoordinateScale> TimeInstant for ModifiedJulianDate<S> {
45 type Duration = Day;
46
47 #[inline]
48 fn difference(&self, other: &Self) -> Day {
49 Day::new(self.raw().value() - other.raw().value())
50 }
51
52 #[inline]
53 fn add_duration(&self, duration: Day) -> Self {
54 MJD::into_time(Day::new(self.raw().value() + duration.value()))
55 }
56}
57
58impl<S: CoordinateScale> TimeInstant for JulianDate<S> {
59 type Duration = Day;
60
61 #[inline]
62 fn difference(&self, other: &Self) -> Day {
63 Day::new(self.raw().value() - other.raw().value())
64 }
65
66 #[inline]
67 fn add_duration(&self, duration: Day) -> Self {
68 JD::into_time(Day::new(self.raw().value() + duration.value()))
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::format::{J2000Seconds, JulianDate, ModifiedJulianDate};
76 use crate::model::scale::TT;
77
78 #[test]
79 fn time_instant_trait_supports_time_and_encoded_dates() {
80 let tt = J2000Seconds::<TT>::new(10.0).to_j2000s();
81 let tt_later = tt.add_duration(Second::new(2.5));
82 assert_eq!(tt_later.difference(&tt), Second::new(2.5));
83
84 let mjd = ModifiedJulianDate::<TT>::new(60_000.0);
85 let mjd_later = mjd.add_duration(Day::new(1.25));
86 assert_eq!(mjd_later.difference(&mjd), Day::new(1.25));
87
88 let jd = JulianDate::<TT>::new(2_460_000.0);
89 let jd_later = jd.add_duration(Day::new(0.5));
90 assert_eq!(jd_later.difference(&jd), Day::new(0.5));
91 }
92}