time_systems/
lib.rs

1pub fn iso_string_to_date_time_array(iso_string: &str) -> [f64; 6] {
2    let year = iso_string[0..4].parse::<f64>().unwrap();
3    let month = iso_string[5..7].parse::<f64>().unwrap();
4    let day = iso_string[8..10].parse::<f64>().unwrap();
5    let hour = iso_string[11..13].parse::<f64>().unwrap();
6    let minute = iso_string[14..16].parse::<f64>().unwrap();
7    let second = iso_string[17..23].parse::<f64>().unwrap();
8    [year, month, day, hour, minute, second]
9}
10
11pub fn iso_string_to_julian_date(iso_string: &str) -> f64 {
12    let date_time_array = iso_string_to_date_time_array(iso_string);
13    let mut year = date_time_array[0];
14    let mut month = date_time_array[1];
15    let day = date_time_array[2];
16    let hour = date_time_array[3];
17    let minute = date_time_array[4];
18    let second = date_time_array[5];
19    if month <= 2.0 {
20        year -= 1.0;
21        month += 12.0;
22    }
23    let mut s_den = 60.0;
24    if is_leap_second_day(iso_string) {
25        s_den = 61.0;
26    }
27    let int_yr_div_100 = (year / 100.0).floor();
28    let b = 2.0 - int_yr_div_100 + (int_yr_div_100 / 4.0).floor();
29    let c = ((second / s_den + minute) / 60.0 + hour) / 24.0;
30    (365.25 * (year + 4716.0)).floor() + (30.6001 * (month + 1.0)).floor() + day + b - 1524.5 + c
31}
32
33pub fn is_leap_second_day(iso_string: &str) -> bool {
34    matches!(
35        &iso_string[0..10],
36        "2016-12-31"
37            | "2015-06-30"
38            | "2012-06-30"
39            | "2008-12-31"
40            | "2005-12-31"
41            | "1998-12-31"
42            | "1997-06-30"
43            | "1995-12-31"
44            | "1994-06-30"
45            | "1993-06-30"
46            | "1992-06-30"
47            | "1990-12-31"
48            | "1989-12-31"
49            | "1987-12-31"
50            | "1985-06-30"
51            | "1983-06-30"
52            | "1982-06-30"
53            | "1981-06-30"
54            | "1979-12-31"
55            | "1978-12-31"
56            | "1977-12-31"
57            | "1976-12-31"
58            | "1975-12-31"
59            | "1974-12-31"
60            | "1973-12-31"
61            | "1972-12-31"
62            | "1972-06-30"
63    )
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_iso_string_to_date_time_array() {
72        assert_eq!(
73            iso_string_to_date_time_array("2021-01-01T00:00:00.000000Z"),
74            [2021.0, 1.0, 1.0, 0.0, 0.0, 0.0]
75        );
76        assert_eq!(
77            iso_string_to_date_time_array("2021-01-01T00:00:00.000000Z"),
78            [2021.0, 1.0, 1.0, 0.0, 0.0, 0.0]
79        );
80        assert_eq!(
81            iso_string_to_date_time_array("2021-01-01T00:00:00.000000Z"),
82            [2021.0, 1.0, 1.0, 0.0, 0.0, 0.0]
83        );
84    }
85
86    #[test]
87    fn test_iso_string_to_julian_date() {
88        assert_eq!(
89            iso_string_to_julian_date("2021-01-01T00:00:00.000000Z"),
90            2459215.5
91        );
92        assert_eq!(
93            iso_string_to_julian_date("1996-10-26T14:20:00.000000Z"),
94            2450383.097222222
95        );
96    }
97}