use crate::util::Date;
use core::f64::consts::TAU;
use libm::floor;
#[derive(Debug, Default, Clone, Copy, PartialEq)]
pub struct TimeStamp {
pub mon: f64,
pub day: f64,
pub hr: f64,
pub min: f64,
pub sec: f64,
}
pub fn days2mdhms(year: u16, days: f64) -> TimeStamp {
let lmonth = [
31.,
if year.is_multiple_of(4) { 29. } else { 28. },
31.,
30.,
31.,
30.,
31.,
31.,
30.,
31.,
30.,
31.,
];
let dayofyr = floor(days);
let mut i = 1;
let mut inttemp = 0.;
while dayofyr > (inttemp + lmonth[i - 1]) && i < 12 {
inttemp += lmonth[i - 1];
i += 1;
}
let mon = i;
let day = dayofyr - inttemp;
let mut temp = (days - dayofyr) * 24.0;
let hr = floor(temp);
temp = (temp - hr) * 60.0;
let min = floor(temp);
let sec = (temp - min) * 60.0;
TimeStamp { mon: mon as f64, day, hr, min, sec }
}
pub fn jday_internal(
year: f64,
mon: f64,
day: f64,
hr: f64,
min: f64,
sec: f64,
msec: Option<f64>,
) -> f64 {
let msec = msec.unwrap_or(0.);
367.0 * year - floor(7. * (year + floor((mon + 9.) / 12.0)) * 0.25)
+ floor((275. * mon) / 9.0)
+ day
+ 1721013.5
+ ((msec / 60000. + sec / 60.0 + min) / 60.0 + hr) / 24.0
}
pub fn jday(date: &Date) -> f64 {
jday_internal(
date.year as f64,
date.month as f64,
date.day as f64,
date.hour as f64,
date.minute as f64,
date.second as f64,
None,
)
}
fn gstime_internal(jdut1: f64) -> f64 {
let tut1 = (jdut1 - 2451545.0) / 36525.0;
let mut temp = -6.2e-6 * tut1 * tut1 * tut1
+ 0.093104 * tut1 * tut1
+ (876600.0 * 3600.0 + 8640184.812866) * tut1
+ 67310.54841; temp = ((temp.to_radians()) / 240.0) % TAU;
if temp < 0.0 {
temp += TAU;
}
temp
}
pub fn gstime(time: &Date) -> f64 {
gstime_internal(jday(time))
}