pub const SECONDS_PER_MINUTE: f64 = 60.0;
pub const SECONDS_PER_HOUR: f64 = 3_600.0;
pub const SECONDS_PER_DAY: f64 = 86_400.0;
pub const SECONDS_PER_JULIAN_YEAR: f64 = 365.25 * SECONDS_PER_DAY;
pub const SECONDS_PER_SIDEREAL_YEAR: f64 = 365.256_363_004 * SECONDS_PER_DAY;
pub const DAYS_PER_JULIAN_CENTURY: f64 = 36_525.0;
pub const J2000_EPOCH_JD: f64 = 2_451_545.0;
#[derive(Clone, Debug)]
pub struct EphemerisTime {
pub epoch_jd: f64,
pub elapsed_s: f64,
}
impl EphemerisTime {
pub fn j2000() -> Self {
Self {
epoch_jd: J2000_EPOCH_JD,
elapsed_s: 0.0,
}
}
pub fn from_jd(jd: f64) -> Self {
Self {
epoch_jd: J2000_EPOCH_JD,
elapsed_s: (jd - J2000_EPOCH_JD) * SECONDS_PER_DAY,
}
}
pub fn advance(&mut self, dt: f64) {
self.elapsed_s += dt;
}
pub fn current_jd(&self) -> f64 {
self.epoch_jd + self.elapsed_s / SECONDS_PER_DAY
}
pub fn centuries_since_j2000(&self) -> f64 {
self.elapsed_s / (DAYS_PER_JULIAN_CENTURY * SECONDS_PER_DAY)
}
pub fn years_elapsed(&self) -> f64 {
self.elapsed_s / SECONDS_PER_JULIAN_YEAR
}
pub fn days_elapsed(&self) -> f64 {
self.elapsed_s / SECONDS_PER_DAY
}
}
pub fn julian_date_to_calendar(jd: f64) -> (i32, u32, u32, u32, u32, f64) {
let jd = jd + 0.5;
let z = jd.floor() as i64;
let f = jd - z as f64;
let a = if z < 2_299_161 {
z
} else {
let alpha = ((z as f64 - 1_867_216.25) / 36_524.25).floor() as i64;
z + 1 + alpha - alpha / 4
};
let b = a + 1524;
let c = ((b as f64 - 122.1) / 365.25).floor() as i64;
let d = (365.25 * c as f64).floor() as i64;
let e = ((b - d) as f64 / 30.6001).floor() as i64;
let day = (b - d - (30.6001 * e as f64).floor() as i64) as u32;
let month = if e < 14 { e - 1 } else { e - 13 } as u32;
let year = if month > 2 { c - 4716 } else { c - 4715 } as i32;
let hours_total = f * 24.0;
let hour = hours_total.floor() as u32;
let minutes_total = (hours_total - hour as f64) * 60.0;
let minute = minutes_total.floor() as u32;
let second = (minutes_total - minute as f64) * 60.0;
(year, month, day, hour, minute, second)
}
pub fn calendar_to_julian_date(
year: i32,
month: u32,
day: u32,
hour: u32,
minute: u32,
second: f64,
) -> f64 {
let (y, m) = if month <= 2 {
(year - 1, month + 12)
} else {
(year, month)
};
let a = y / 100;
let b = 2 - a + a / 4;
let jd = (365.25 * (y + 4716) as f64).floor()
+ (30.6001 * (m + 1) as f64).floor()
+ day as f64
+ b as f64
- 1524.5;
jd + (hour as f64 + minute as f64 / 60.0 + second / 3600.0) / 24.0
}