pub const ATTOSECONDS_PER_SECOND: i128 = 1_000_000_000_000_000_000;
pub const ATTOSECONDS_PER_PICOSECOND: i128 = 1_000_000;
pub const ATTOSECONDS_PER_DAY: i128 = 86_400 * ATTOSECONDS_PER_SECOND;
pub const PICOSECONDS_PER_DAY: i128 = ATTOSECONDS_PER_DAY / ATTOSECONDS_PER_PICOSECOND;
#[inline]
pub fn split_ticks_into_day_parts(ticks: i128, ticks_per_day: i128) -> (i128, i128) {
let days = ticks.div_euclid(ticks_per_day);
let rem = ticks.rem_euclid(ticks_per_day);
(days, rem)
}
#[inline]
pub fn ticks_to_brightdate(ticks: i128, ticks_per_day: i128) -> f64 {
let (days, rem) = split_ticks_into_day_parts(ticks, ticks_per_day);
days as f64 + (rem as f64 / ticks_per_day as f64)
}
pub fn brightdate_to_attoseconds(bd: f64) -> Result<i128, crate::types::BrightDateError> {
if !bd.is_finite() {
return Err(crate::types::BrightDateError::InvalidInput(format!(
"expected finite BrightDate, got {bd}"
)));
}
let days_floor = bd.floor();
let frac = bd - days_floor;
let days_i = days_floor as i128;
let frac_as = (frac * ATTOSECONDS_PER_DAY as f64).round() as i128;
Ok(days_i * ATTOSECONDS_PER_DAY + frac_as)
}
pub fn brightdate_to_picoseconds(bd: f64) -> Result<i128, crate::types::BrightDateError> {
if !bd.is_finite() {
return Err(crate::types::BrightDateError::InvalidInput(format!(
"expected finite BrightDate, got {bd}"
)));
}
let days_floor = bd.floor();
let frac = bd - days_floor;
let days_i = days_floor as i128;
let frac_ps = (frac * PICOSECONDS_PER_DAY as f64).round() as i128;
Ok(days_i * PICOSECONDS_PER_DAY + frac_ps)
}