1//! Utility functions.
2
3/// Returns if the provided year is a leap year in the proleptic Gregorian calendar. Uses
4/// [astronomical year numbering](https://en.wikipedia.org/wiki/Astronomical_year_numbering).
5///
6/// ```rust
7/// # use time::util::is_leap_year;
8/// assert!(!is_leap_year(1900));
9/// assert!(is_leap_year(2000));
10/// assert!(is_leap_year(2004));
11/// assert!(!is_leap_year(2005));
12/// assert!(!is_leap_year(2100));
13/// ```
14pub const fn is_leap_year(year: i32) -> bool {
15 year % 4 == 0 && (year % 25 != 0 || year % 16 == 0)
16}
17
18/// Get the number of calendar days in a given year.
19///
20/// The returned value will always be either 365 or 366.
21///
22/// ```rust
23/// # use time::util::days_in_year;
24/// assert_eq!(days_in_year(1900), 365);
25/// assert_eq!(days_in_year(2000), 366);
26/// assert_eq!(days_in_year(2004), 366);
27/// assert_eq!(days_in_year(2005), 365);
28/// assert_eq!(days_in_year(2100), 365);
29/// ```
30pub const fn days_in_year(year: i32) -> u16 {
31 if is_leap_year(year) { 366 } else { 365 }
32}
33
34/// Get the number of weeks in the ISO year.
35///
36/// The returned value will always be either 52 or 53.
37///
38/// ```rust
39/// # use time::util::weeks_in_year;
40/// assert_eq!(weeks_in_year(2019), 52);
41/// assert_eq!(weeks_in_year(2020), 53);
42/// ```
43pub const fn weeks_in_year(year: i32) -> u8 {
44 match year.rem_euclid(400) {
45 4 | 9 | 15 | 20 | 26 | 32 | 37 | 43 | 48 | 54 | 60 | 65 | 71 | 76 | 82 | 88 | 93 | 99
46 | 105 | 111 | 116 | 122 | 128 | 133 | 139 | 144 | 150 | 156 | 161 | 167 | 172 | 178
47 | 184 | 189 | 195 | 201 | 207 | 212 | 218 | 224 | 229 | 235 | 240 | 246 | 252 | 257
48 | 263 | 268 | 274 | 280 | 285 | 291 | 296 | 303 | 308 | 314 | 320 | 325 | 331 | 336
49 | 342 | 348 | 353 | 359 | 364 | 370 | 376 | 381 | 387 | 392 | 398 => 53,
50 _ => 52,
51 }
52}
53