1use qtty::Day;
7
8use crate::representation::{JulianDate, ModifiedJulianDate};
9use crate::scale::CoordinateScale;
10use crate::scale::TT;
11use crate::time::Time;
12use qtty::Second;
13
14pub trait TimeInstant: Copy + PartialOrd {
18 type Duration;
20
21 fn difference(&self, other: &Self) -> Self::Duration;
23
24 fn add_duration(&self, duration: Self::Duration) -> Self;
26}
27
28impl TimeInstant for Time<TT> {
29 type Duration = Second;
30
31 #[inline]
32 fn difference(&self, other: &Self) -> Second {
33 *self - *other
34 }
35
36 #[inline]
37 fn add_duration(&self, dur: Second) -> Self {
38 *self + dur
39 }
40}
41
42impl<S: CoordinateScale> TimeInstant for ModifiedJulianDate<S> {
43 type Duration = Day;
44
45 #[inline]
46 fn difference(&self, other: &Self) -> Day {
47 Day::new(self.raw().value() - other.raw().value())
48 }
49
50 #[inline]
51 fn add_duration(&self, duration: Day) -> Self {
52 ModifiedJulianDate::<S>::new_unchecked(Day::new(self.raw().value() + duration.value()))
53 }
54}
55
56impl<S: CoordinateScale> TimeInstant for JulianDate<S> {
57 type Duration = Day;
58
59 #[inline]
60 fn difference(&self, other: &Self) -> Day {
61 Day::new(self.raw().value() - other.raw().value())
62 }
63
64 #[inline]
65 fn add_duration(&self, duration: Day) -> Self {
66 JulianDate::<S>::new_unchecked(Day::new(self.raw().value() + duration.value()))
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use crate::representation::{J2000Seconds, JulianDate, ModifiedJulianDate};
74 use crate::scale::TT;
75
76 #[test]
77 fn time_instant_trait_supports_time_and_encoded_dates() {
78 let tt = J2000Seconds::<TT>::try_new(Second::new(10.0))
79 .unwrap()
80 .to_time();
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}