use qtty::*;
use std::ops::Add;
use super::instant::Time;
use super::scales::{JD, MJD};
impl Time<JD> {
pub const J2000: Self = Self::new(2_451_545.0);
pub const JULIAN_YEAR: Days = Days::new(365.25);
pub const JULIAN_CENTURY: Days = Days::new(36_525.0);
pub const JULIAN_MILLENNIUM: Days = Days::new(365_250.0);
#[inline]
pub fn julian_millennias(&self) -> Millennia {
Millennia::new(
((*self - Self::J2000) / Self::JULIAN_MILLENNIUM)
.simplify()
.value(),
)
}
#[inline]
pub fn julian_centuries(&self) -> Centuries {
Centuries::new(
((*self - Self::J2000) / Self::JULIAN_CENTURY)
.simplify()
.value(),
)
}
#[inline]
pub fn julian_years(&self) -> JulianYears {
JulianYears::new(
((*self - Self::J2000) / Self::JULIAN_YEAR)
.simplify()
.value(),
)
}
pub fn tt_to_tdb(jd_tt: Self) -> Self {
jd_tt + super::scales::tdb_minus_tt_days(jd_tt.quantity())
}
#[inline]
pub fn to_mjd(&self) -> Time<MJD> {
self.to::<MJD>()
}
}
impl Add<Years> for Time<JD> {
type Output = Self;
fn add(self, years: Years) -> Self {
self + Days::new(years.value() * Self::JULIAN_YEAR.value())
}
}
impl From<JulianYears> for Time<JD> {
fn from(years: JulianYears) -> Self {
Self::J2000 + years.to::<Day>()
}
}
impl From<Time<JD>> for JulianYears {
fn from(jd: Time<JD>) -> Self {
jd.julian_years()
}
}
impl From<Centuries> for Time<JD> {
fn from(centuries: Centuries) -> Self {
Self::J2000 + Days::new(centuries.value() * Self::JULIAN_CENTURY.value())
}
}
impl From<Time<JD>> for Centuries {
fn from(jd: Time<JD>) -> Self {
jd.julian_centuries()
}
}
impl From<Millennia> for Time<JD> {
fn from(millennia: Millennia) -> Self {
Self::J2000 + Days::new(millennia.value() * Self::JULIAN_MILLENNIUM.value())
}
}
impl From<Time<JD>> for Millennia {
fn from(jd: Time<JD>) -> Self {
jd.julian_millennias()
}
}
#[cfg(test)]
mod tests {
use crate::{Time, JD, MJD};
#[test]
fn to_mjd_convenience_matches_to_generic() {
let jd = Time::<JD>::J2000;
let via_convenience = jd.to_mjd();
let via_generic = jd.to::<MJD>();
assert_eq!(via_convenience.value(), via_generic.value());
}
}