refactor: code deduplication, extracted conversion into utils module
This commit is contained in:
parent
c4045c9142
commit
3913e79acf
@ -13,48 +13,36 @@ pub struct NaiveJulianDate {
|
|||||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
struct JulianDayNumber (u32);
|
struct JulianDayNumber (u32);
|
||||||
|
|
||||||
impl From<NaiveDate> for JulianDayNumber {
|
pub struct JulianDayNumberUtils;
|
||||||
fn from (value: NaiveDate) -> Self {
|
|
||||||
|
impl JulianDayNumberUtils {
|
||||||
|
|
||||||
|
/// Given a month, day, and year, converts them into a julian day number (first return tuple member)
|
||||||
|
/// Second tuple member -- value of g that is required to calculate additional subtrahend for J for gregorian dates
|
||||||
|
pub fn julian_into_julian_day_number (day: i32, month: i32, year: i32) -> (i32, i32) {
|
||||||
use tables::julian_gregorian::*;
|
use tables::julian_gregorian::*;
|
||||||
|
|
||||||
let D = value.day();
|
let h = month - m;
|
||||||
let M = value.month();
|
let g = year + y - (n - h) / n;
|
||||||
let Y = value.year();
|
|
||||||
|
|
||||||
|
|
||||||
let h = M as i32 - m;
|
|
||||||
let g = Y as i32 + y - (n - h) / n;
|
|
||||||
let f = (h - 1 + n) % n;
|
let f = (h - 1 + n) % n;
|
||||||
let e = (p * g + q) / r + D as i32 - 1 - j;
|
let e = (p * g + q) / r + day - 1 - j;
|
||||||
|
|
||||||
let J = e + (s * f + t) / u;
|
(e + (s * f + t) / u, g)
|
||||||
|
|
||||||
let J = J - (3 * ((g + A) / 100)) / 4 - C;
|
|
||||||
|
|
||||||
Self(J as u32)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<NaiveJulianDate> for JulianDayNumber {
|
pub fn gregorian_into_julian_day_number (day: i32, month: i32, year: i32) -> i32 {
|
||||||
fn from (NaiveJulianDate { day: D, year: Y, month: M }: NaiveJulianDate) -> Self {
|
use tables::julian_gregorian::*;
|
||||||
|
let (J, g) = Self::julian_into_julian_day_number(day, month, year);
|
||||||
|
J - (3 * ((g + A) / 100)) / 4 - C
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts Julian Day Number into a generic year-month-day tuple.
|
||||||
|
/// For gregorian dates, `f_extra` must be calculated with `JulianDayNumberUtils::gregorian_f_extra_for_julian_day`.
|
||||||
|
/// For julian dates, f_extra must be 0.
|
||||||
|
pub fn julian_day_number_into_ymd (julian_day: i32, f_extra: i32) -> (i32, u32, u32) {
|
||||||
use tables::julian_gregorian::*;
|
use tables::julian_gregorian::*;
|
||||||
|
|
||||||
let h = M as i32 - m;
|
let f = julian_day + j + f_extra;
|
||||||
let g = Y as i32 + y - (n - h) / n;
|
|
||||||
let f = (h - 1 + n) % n;
|
|
||||||
let e = (p * g + q) / r + D as i32 - 1 - j;
|
|
||||||
|
|
||||||
let J = e + (s * f + t) / u;
|
|
||||||
|
|
||||||
Self(J as u32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<JulianDayNumber> for NaiveJulianDate {
|
|
||||||
fn from (JulianDayNumber(J): JulianDayNumber) -> Self {
|
|
||||||
use tables::julian_gregorian::*;
|
|
||||||
|
|
||||||
let f = J as i32 + j;
|
|
||||||
let e = r * f + v;
|
let e = r * f + v;
|
||||||
let g = e % p / r;
|
let g = e % p / r;
|
||||||
let h = u * g + w;
|
let h = u * g + w;
|
||||||
@ -63,6 +51,33 @@ impl From<JulianDayNumber> for NaiveJulianDate {
|
|||||||
let month = ((h / s + m) % n + 1) as u32;
|
let month = ((h / s + m) % n + 1) as u32;
|
||||||
let year = e / p - y + (n + m - month as i32) / n;
|
let year = e / p - y + (n + m - month as i32) / n;
|
||||||
|
|
||||||
|
(year, month, day)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns extra `f` addend for calculating Gregorian calendar date from Julian Day Number
|
||||||
|
pub fn gregorian_f_extra_for_julian_day (julian_day: i32) -> i32 {
|
||||||
|
use tables::julian_gregorian::*;
|
||||||
|
(((julian_day * 4 + B) / 146_097) * 3) / 4 + C
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NaiveDate> for JulianDayNumber {
|
||||||
|
fn from (value: NaiveDate) -> Self {
|
||||||
|
let D = value.day(); let M = value.month(); let Y = value.year();
|
||||||
|
let J = JulianDayNumberUtils::gregorian_into_julian_day_number(D as i32, M as i32, Y);
|
||||||
|
Self(J as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NaiveJulianDate> for JulianDayNumber {
|
||||||
|
fn from (NaiveJulianDate { day: D, year: Y, month: M }: NaiveJulianDate) -> Self {
|
||||||
|
Self(JulianDayNumberUtils::julian_into_julian_day_number(D as i32, M as i32, Y).0 as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<JulianDayNumber> for NaiveJulianDate {
|
||||||
|
fn from (JulianDayNumber(jd): JulianDayNumber) -> Self {
|
||||||
|
let (year, month, day) = JulianDayNumberUtils::julian_day_number_into_ymd(jd as i32, 0);
|
||||||
Self { year, day, month }
|
Self { year, day, month }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,17 +85,8 @@ impl From<JulianDayNumber> for NaiveJulianDate {
|
|||||||
|
|
||||||
impl TryFrom<JulianDayNumber> for NaiveDate {
|
impl TryFrom<JulianDayNumber> for NaiveDate {
|
||||||
type Error = ConversionError;
|
type Error = ConversionError;
|
||||||
fn try_from (JulianDayNumber(J): JulianDayNumber) -> Result<Self, Self::Error> {
|
fn try_from (JulianDayNumber(jd): JulianDayNumber) -> Result<Self, Self::Error> {
|
||||||
use tables::julian_gregorian::*;
|
let (year, month, day) = JulianDayNumberUtils::julian_day_number_into_ymd(jd as i32, JulianDayNumberUtils::gregorian_f_extra_for_julian_day(jd as i32));
|
||||||
|
|
||||||
let f = J as i32 + j + (((J as i32 * 4 + B) / 146_097) * 3) / 4 + C;
|
|
||||||
let e = r * f + v;
|
|
||||||
let g = e % p / r;
|
|
||||||
let h = u * g + w;
|
|
||||||
|
|
||||||
let day = (h % s / u + 1) as u32;
|
|
||||||
let month = ((h / s + m) % n + 1) as u32;
|
|
||||||
let year = e / p - y + (n + m - month as i32) / n;
|
|
||||||
|
|
||||||
Self::from_ymd_opt(year, month, day).ok_or_else(|| ConversionError::Generic)
|
Self::from_ymd_opt(year, month, day).ok_or_else(|| ConversionError::Generic)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user