37 lines
984 B
Rust
37 lines
984 B
Rust
use chrono::{Datelike, NaiveDate, Weekday};
|
|
|
|
pub fn is_leap_year(year: i32) -> bool {
|
|
NaiveDate::from_ymd_opt(year, 2, 29).is_some()
|
|
}
|
|
|
|
pub fn is_iso_leap_year(year: i32) -> bool {
|
|
NaiveDate::from_isoywd_opt(year, 53, Weekday::Sun).is_some()
|
|
}
|
|
|
|
pub fn year_length(year: i32) -> u32 {
|
|
NaiveDate::from_ymd_opt(year, 12, 31).unwrap().ordinal()
|
|
}
|
|
|
|
pub fn month_length(year: i32, month: u32) -> u32 {
|
|
NaiveDate::from_ymd_opt(year, month + 1, 1)
|
|
.unwrap_or_else(|| NaiveDate::from_ymd_opt(year + 1, 1, 1).unwrap())
|
|
.pred_opt()
|
|
.unwrap()
|
|
.day()
|
|
}
|
|
|
|
// Length of an ISO week year in days.
|
|
pub fn iso_year_length(year: i32) -> u32 {
|
|
if is_iso_leap_year(year) {
|
|
53 * 7
|
|
} else {
|
|
52 * 7
|
|
}
|
|
}
|
|
|
|
pub fn add_months(year: i32, month: u32, delta: i32) -> (i32, u32) {
|
|
let month0 = (month as i32) - 1 + delta;
|
|
let year = year + month0.div_euclid(12);
|
|
let month = month0.rem_euclid(12) as u32 + 1;
|
|
(year, month)
|
|
}
|