chrono_node/calculation/
years.rs1use crate::calculation::duration::{add_duration, Duration, DurationUnit};
4use crate::core::js_date::JsDate;
5
6pub fn find_most_likely_ad_year(year_number: i64) -> i64 {
8 if year_number < 100 {
9 if year_number > 50 {
10 year_number + 1900
11 } else {
12 year_number + 2000
13 }
14 } else {
15 year_number
16 }
17}
18
19pub fn find_year_closest_to_ref(ref_date: JsDate, day: i64, month: i64) -> i64 {
21 let mut date = ref_date;
22 date.set_month(month - 1);
23 date.set_date(day);
24 let next_year = add_duration(date, &mut Duration::from_pairs(&[(DurationUnit::Year, 1.0)]));
25 let last_year = add_duration(date, &mut Duration::from_pairs(&[(DurationUnit::Year, -1.0)]));
26 let distance = |d: JsDate| match (d.get_time(), ref_date.get_time()) {
27 (Some(a), Some(b)) => Some((a - b).abs()),
28 _ => None,
29 };
30 let lt = |a: Option<i64>, b: Option<i64>| matches!((a, b), (Some(a), Some(b)) if a < b);
32 if lt(distance(next_year), distance(date)) {
33 date = next_year;
34 } else if lt(distance(last_year), distance(date)) {
35 date = last_year;
36 }
37 date.get_full_year()
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn most_likely_year() {
46 assert_eq!(find_most_likely_ad_year(97), 1997);
47 assert_eq!(find_most_likely_ad_year(12), 2012);
48 assert_eq!(find_most_likely_ad_year(50), 2050);
49 assert_eq!(find_most_likely_ad_year(2012), 2012);
50 }
51
52 #[test]
53 fn closest_year() {
54 let r = JsDate::parse_iso("2012-12-20T00:00:00.000Z").unwrap();
55 assert_eq!(find_year_closest_to_ref(r, 2, 1), 2013);
56 let r = JsDate::parse_iso("2013-01-05T00:00:00.000Z").unwrap();
57 assert_eq!(find_year_closest_to_ref(r, 28, 12), 2012);
58 assert_eq!(find_year_closest_to_ref(r, 1, 6), 2013);
59 }
60}