use crate::{Dt, Real, Scale, TDB0_ATTOS, TT_TAI_OFFSET, sin};
impl Dt {
pub const fn tdb_minus_tt(seconds_since_j2000_tt: Real) -> Real {
const J2000_SEC_PER_MILLENNIUM: Real = 31_557_600_000.0;
let t = seconds_since_j2000_tt / J2000_SEC_PER_MILLENNIUM; let mut correction = f!(0.0);
let g = f!(6283.075849991) * t + f!(6.240054195);
let e = f!(0.0167086342) - f!(0.0004203654) * t - f!(0.0000126734) * t * t
+ f!(0.0000001444) * t * t * t
- f!(0.0000000002) * t * t * t * t
+ f!(0.0000000003) * t * t * t * t * t;
let k = f!(0.09897232);
let varpi = f!(-0.00000257) - f!(0.05551247) * t;
correction += k * e * sin(g + varpi + f!(0.01671) * sin(g));
const LTE440_TERMS: [(Real, Real, Real); 12] = [
(0.00012630813184, 77713.771468120, 5.18472464), (0.00001937467715, 5753.384884897, 1.33855843), (0.00001370088760, 12566.151699983, 3.07602294), (0.00000747520418, 5574.656149776, 3.32446352), (0.00000424397312, 4320.34946237, 3.43186281), (0.00000376051430, 377.97977422, 0.92358639), (0.00000293368121, 161002.466707021, 1.09317212), (0.00000267752983, 6208.659051973, 1.51225314), (0.00000236687890, 71430.993657045, 5.21748801), (0.00000185820098, 211.334300759, 2.56843762), (0.00000109742615, 3929.675646567, 4.67635157), (0.00000108850698, 7859.351293133, 2.99248981), ];
let mut i = 0;
while i < 12 {
let (amp, freq, phase) = LTE440_TERMS[i];
correction += amp * sin(freq * t + phase);
i += 1;
}
correction += f!(0.00000000065) * sin(f!(6069.776754) * t + f!(4.021194));
correction += f!(0.00000000033) * sin(f!(213.299095) * t + f!(5.543132));
correction += f!(-0.00000000196) * sin(f!(6208.294251) * t + f!(5.696701));
correction += f!(-0.00000000173) * sin(f!(74.781599) * t + f!(2.435900));
correction += f!(0.00000003638) * t * t;
correction
}
pub const fn tai_to_tdb(tai: Self) -> Self {
let tt = tai.add(TT_TAI_OFFSET);
let correction = Self::tdb_minus_tt(tt.to_sec_f());
tt.add(Dt::from_sec_f(correction))
}
pub const fn tdb_to_tai(tdb: Self) -> Self {
let elapsed = Self::to_attos_since_tcg_tcb_epoch(tdb);
let linear_span = Self::mul_lb(elapsed); let mut tt = tdb
.sub(Dt::from_attos(linear_span, Scale::TAI))
.sub(Dt::from_attos(TDB0_ATTOS, Scale::TAI));
let mut i = 0u32;
while i < 8 {
let p = Self::tdb_minus_tt(tt.to_sec_f());
let new_tt = tdb.sub(Dt::from_sec_f(p));
let delta = new_tt.to_diff_raw(tt);
if delta.sec == 0 && delta.attos < 1 {
tt = new_tt;
break;
}
tt = new_tt;
i += 1;
}
tt.sub(TT_TAI_OFFSET)
}
}