simple_datetime_rs/utils/
date_util.rs

1use crate::constants::MONTH_DAYS;
2
3#[inline]
4pub fn next_leap_year(year:u64) -> u64 {
5    recent_leap_year(year + 4)
6}
7#[inline]
8pub fn recent_leap_year(year:u64) -> u64 {
9    year - (year % 4)
10}
11#[inline]
12pub fn leap_year(year:u64) -> bool {
13    (year & 3) == 0 && (year % 100 != 0 || year % 400 == 0)
14}
15#[inline]
16pub fn month_index(month:u64) -> usize {
17    (month.saturating_sub(1)) as usize
18}
19
20pub fn month_days(month:u64, leap_year:bool) -> u64 {
21    if leap_year && month == 2 {return MONTH_DAYS[month_index(month)] + 1;}
22    MONTH_DAYS[month_index(month)]
23}
24#[inline]
25pub fn before_leap(month:u64) -> bool {
26    month < 3
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    #[test]
34    fn test_date_leap_year(){
35        assert!(leap_year(2020));
36        assert!(!leap_year(2018));
37        assert!(leap_year(2016));
38    }
39
40    #[test]
41    fn test_date_recent_leap_year(){
42        assert_eq!(recent_leap_year(2020), 2020);
43        assert_eq!(recent_leap_year(2019), 2016);
44    }
45
46    #[test]
47    fn test_date_next_leap_year(){
48        assert_eq!(next_leap_year(2020), 2024);
49        assert_eq!(next_leap_year(2019), 2020);
50    }
51
52    #[test]
53    fn test_month_days() {
54        // Regular months
55        assert_eq!(month_days(1, false), 31); // January
56        assert_eq!(month_days(3, false), 31); // March
57        assert_eq!(month_days(4, false), 30); // April
58        assert_eq!(month_days(6, false), 30); // June
59        assert_eq!(month_days(9, false), 30); // September
60        assert_eq!(month_days(11, false), 30); // November
61        assert_eq!(month_days(12, false), 31); // December
62        
63        // February in non-leap year
64        assert_eq!(month_days(2, false), 28);
65        
66        // February in leap year
67        assert_eq!(month_days(2, true), 29);
68        
69        // All months in leap year (should be same except February)
70        for month in 1..=12 {
71            if month != 2 {
72                assert_eq!(month_days(month, true), month_days(month, false));
73            }
74        }
75    }
76
77    #[test]
78    fn test_before_leap() {
79        assert!(before_leap(1)); // January
80        assert!(before_leap(2)); // February
81        assert!(!before_leap(3)); // March
82        assert!(!before_leap(4)); // April
83        assert!(!before_leap(12)); // December
84    }
85
86    #[test]
87    fn test_month_index() {
88        assert_eq!(month_index(1), 0);
89        assert_eq!(month_index(6), 5);
90        assert_eq!(month_index(12), 11);
91    }
92
93    #[test]
94    fn test_leap_year_edge_cases() {
95        // Test century years
96        assert!(leap_year(2000)); // Divisible by 400
97        assert!(!leap_year(1900)); // Divisible by 100 but not 400
98        assert!(!leap_year(1800)); // Divisible by 100 but not 400
99        assert!(!leap_year(1700)); // Divisible by 100 but not 400
100        
101        // Test regular years
102        assert!(leap_year(2004)); // Divisible by 4
103        assert!(leap_year(2008)); // Divisible by 4
104        assert!(!leap_year(2001)); // Not divisible by 4
105        assert!(!leap_year(2002)); // Not divisible by 4
106        assert!(!leap_year(2003)); // Not divisible by 4
107    }
108
109    #[test]
110    fn test_recent_leap_year_edge_cases() {
111        assert_eq!(recent_leap_year(2020), 2020); // Already a leap year
112        assert_eq!(recent_leap_year(2021), 2020); // Previous leap year
113        assert_eq!(recent_leap_year(2022), 2020); // Previous leap year
114        assert_eq!(recent_leap_year(2023), 2020); // Previous leap year
115        assert_eq!(recent_leap_year(2024), 2024); // Next leap year
116    }
117
118    #[test]
119    fn test_next_leap_year_edge_cases() {
120        assert_eq!(next_leap_year(2020), 2024); // Current leap year
121        assert_eq!(next_leap_year(2021), 2024); // Next leap year
122        assert_eq!(next_leap_year(2022), 2024); // Next leap year
123        assert_eq!(next_leap_year(2023), 2024); // Next leap year
124        assert_eq!(next_leap_year(2024), 2028); // Next leap year after current
125    }
126
127}