deep_time/dt/
conversions_mars.rs1use crate::{
2 Dt, MARS_REF_TT, MARS_REF_TT_ATTOS, MARS_SOL_ATTOS, MARS_SOL_LENGTH_SEC, Real, Scale,
3 clamp_i128_to_i64, floor_f, to_sec_f,
4};
5
6impl Dt {
7 #[inline]
9 pub(crate) const fn to_attos_since_mars_msd_epoch(numerical_tt: Dt) -> i128 {
10 numerical_tt.to_attos() - MARS_REF_TT_ATTOS
11 }
12
13 pub const fn to_msd_exact(&self, current: Scale) -> (i64, u128) {
18 let tt = self.to(current, Scale::TT);
19 let elapsed = Self::to_attos_since_mars_msd_epoch(tt);
20 let whole_sols = elapsed.div_euclid(MARS_SOL_ATTOS);
21 let frac_attos = elapsed.rem_euclid(MARS_SOL_ATTOS) as u128;
22
23 (clamp_i128_to_i64(whole_sols), frac_attos)
24 }
25
26 #[inline]
29 pub const fn to_mtc(&self, current: Scale) -> Dt {
30 let (_, frac_attos) = self.to_msd_exact(current);
31 Dt::from_attos(frac_attos as i128, Scale::TAI)
32 }
33
34 pub const fn from_msd_exact(whole_sols: i64, frac_attos: u128) -> Self {
36 let elapsed_attos = (whole_sols as i128) * MARS_SOL_ATTOS + frac_attos as i128;
37 let tt = MARS_REF_TT.add(Dt::from_attos(elapsed_attos, Scale::TAI));
38 Self::from(tt.sec, tt.attos, Scale::TT)
39 }
40
41 pub const fn from_msd(msd: Real) -> Self {
44 let whole = floor_f(msd) as i64;
45 let frac = msd - f!(whole);
46 let frac_span = Dt::from_sec_f(frac * MARS_SOL_LENGTH_SEC);
47 Self::from_msd_exact(whole, frac_span.to_attos() as u128)
48 }
49
50 #[inline]
53 pub const fn to_msd(&self, current: Scale) -> Real {
54 let (whole, frac) = self.to_msd_exact(current);
55 f!(whole) + to_sec_f(frac) / MARS_SOL_LENGTH_SEC
56 }
57}