pub const MJD0: f64 = 2400000.5;
pub const DTROPYEAR: f64 = 365.242198781;
pub const DJYEAR: f64 = 365.25;
pub const DJCENT: f64 = 36525.0;
pub const DJMILL: f64 = 365250.0;
pub const SECDAY: f64 = 86400.0;
pub const MSECINDAY: f64 = 86400000.0;
pub const J2000: f64 = 51544.5;
pub const J1950: f64 = 33282.0;
pub const J1900: f64 = 15019.5;
pub const B1950: f64 = 33281.92345905;
pub const B1900: f64 = 15019.81352;
#[derive(Debug)]
pub struct Adate {
pub year: i16,
pub month: u8,
pub day: u8,
pub hour: u8,
pub min: u8,
pub sec: u8,
pub msec: u16,
}
impl Adate {
pub fn mjd(&self) -> f64 {
if (self.year >= -4799) || (self.month >= 1) || (self.month <= 12) {
let my: i32 = (self.month as i32 - 14) / 12;
let iypmy: i32 = self.year as i32 + my;
((1461 * (iypmy + 4800)) / 4 + (367 * (self.month as i32 - 2 - 12 * my)) / 12
- (3 * ((iypmy + 4900) / 100)) / 4
+ self.day as i32
- 2432076) as f64
+ self.dayfrac()
} else {
f64::NAN
}
}
pub fn dayfrac(&self) -> f64 {
(self.msec as f64
+ (self.sec as f64 + (self.min as f64 + self.hour as f64 * 60.0) * 60.0) * 1000.0)
/ MSECINDAY
}
pub fn day_of_year(&self) -> i16 {
if is_leep_year(self.year) {
(275 * self.month as i16 / 9) - ((self.month as i16 + 9) / 12) + self.day as i16 - 30
} else {
(275 * self.month as i16 / 9) - 2 * ((self.month as i16 + 9) / 12) + self.day as i16
- 30
}
}
}
pub fn mjd_adate(mjd: f64) -> Adate {
if (mjd >= -2468570.0) || (mjd < 997599999.5) {
let msmjd = (mjd * MSECINDAY).round() as i64;
let mut msdf = msmjd % 86400000i64;
let mut lmjd = msmjd / 86400000i64;
if msmjd >= 0 {
lmjd += 1i64;
} else {
msdf += 86400000i64;
}
let mut l = lmjd + 68569i64 + 2400000i64;
let n = (4i64 * l) / 146097i64;
l -= (146097i64 * n + 3i64) / 4i64;
let i = (4000i64 * (l + 1i64)) / 1461001i64;
l -= (1461i64 * i) / 4i64 - 31i64;
let k = (80i64 * l) / 2447i64;
let dy = (l - (2447i64 * k) / 80i64) as u8;
l = k / 11i64;
let mh = (k + 2i64 - 12i64 * l) as u8;
let yr = (100i64 * (n - 49i64) + i + l) as i16;
let hr = (msdf / 3600000i64) as u8;
msdf = msdf % 3600000i64;
let mn = (msdf / 60000i64) as u8;
msdf = msdf % 60000i64;
let sc = (msdf / 1000i64) as u8;
let ms = (msdf % 1000i64) as u16;
Adate {
year: yr,
month: mh,
day: dy,
hour: hr,
min: mn,
sec: sc,
msec: ms,
}
} else {
Adate {
year: i16::MAX,
month: u8::MAX,
day: u8::MAX,
hour: u8::MAX,
min: u8::MAX,
sec: u8::MAX,
msec: u16::MAX,
}
}
}
pub fn mjd_jd(mjd: f64) -> f64 {
mjd + MJD0
}
pub fn jd_mjd(jd: f64) -> f64 {
jd - MJD0
}
pub fn mjd_jep(mjd: f64) -> f64 {
2000.0 + (mjd - J2000) / DJYEAR
}
pub fn jep_mjd(jep: f64) -> f64 {
J2000 + (jep - 2000.0) * DJYEAR
}
pub fn mjd_bep(mjd: f64) -> f64 {
1900.0 + (mjd - B1900) / DTROPYEAR
}
pub fn bep_mjd(bep: f64) -> f64 {
B1900 + (bep - 1900.0) * DTROPYEAR
}
pub fn mjd_dayfrac(mjd: f64) -> f64 {
if mjd >= 0.0 {
mjd % 1.0
} else {
mjd % 1.0 + 1.0
}
}
pub fn is_leep_year(year: i16) -> bool {
if year % 100 == 0 {
year % 400 == 0
} else {
year % 4 == 0
}
}