deep_time/dt/
conversions_mars.rs1use crate::{
2 ATTOS_PER_SEC_I128, Dt, J2000_JD_TT, MARS_MSD_REF_JD_INT, MARS_MSD_REF_TOD_SEC,
3 MARS_MSD_REF_TOD_SUBSEC, MARS_REF_TT, MARS_SOL_ATTOS, MARS_SOL_LENGTH_SEC, Real,
4 SEC_PER_DAYI64, SEC_PER_DAYI128, Scale, TSpan, floor_f, to_sec_f,
5};
6
7impl Dt {
8 pub(crate) const fn elapsed_to_attos_since_mars_ref(numerical_tt: TSpan) -> i128 {
10 let days_since_j2000 = numerical_tt.sec.div_euclid(SEC_PER_DAYI64);
11 let tod_sec = numerical_tt.sec.rem_euclid(SEC_PER_DAYI64);
12
13 let jd_days = J2000_JD_TT + days_since_j2000;
14 let days_diff = jd_days - MARS_MSD_REF_JD_INT;
15
16 let mut sec_diff = (days_diff as i128) * SEC_PER_DAYI128
17 + (tod_sec as i128 - MARS_MSD_REF_TOD_SEC as i128);
18 let mut attos_diff = (numerical_tt.attos as i128) - (MARS_MSD_REF_TOD_SUBSEC as i128);
19
20 if attos_diff < 0 {
21 attos_diff += ATTOS_PER_SEC_I128;
22 sec_diff -= 1;
23 }
24
25 sec_diff * ATTOS_PER_SEC_I128 + attos_diff
26 }
27
28 pub const fn to_msd_exact(self) -> (i64, u128) {
33 let tt = self.to(Scale::TT);
34 let elapsed = Self::elapsed_to_attos_since_mars_ref(tt);
35 let attos_per_sol = MARS_SOL_ATTOS;
36
37 let whole_sols = elapsed.div_euclid(attos_per_sol) as i64;
38 let frac_attos = elapsed.rem_euclid(attos_per_sol) as u128;
39
40 (whole_sols, frac_attos)
41 }
42
43 #[inline]
46 pub const fn to_mtc(self) -> TSpan {
47 let (_, frac_attos) = self.to_msd_exact();
48 TSpan::from_attos(frac_attos as i128)
49 }
50
51 pub const fn from_msd_exact(whole_sols: i64, frac_attos: u128) -> Self {
53 let elapsed_attos = (whole_sols as i128) * MARS_SOL_ATTOS + frac_attos as i128;
54
55 let tt = MARS_REF_TT.add(TSpan::from_attos(elapsed_attos));
56 Self::from(tt.sec, tt.attos, Scale::TT)
57 }
58
59 pub const fn from_msd(msd: Real) -> Self {
62 let whole = floor_f(msd) as i64;
63 let frac = msd - f!(whole);
64 let frac_span = TSpan::from_sec_f(frac * MARS_SOL_LENGTH_SEC);
65 Self::from_msd_exact(whole, frac_span.to_attos() as u128)
66 }
67
68 #[inline]
71 pub const fn to_msd(self) -> Real {
72 let (whole, frac) = self.to_msd_exact();
73 f!(whole) + to_sec_f(frac) / MARS_SOL_LENGTH_SEC
74 }
75}