pub use jiff::civil::{Date, DateTime, Time, Weekday};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct YearMonth {
year: i16,
month: i8,
}
impl YearMonth {
pub fn new(year: i16, month: i8) -> Self {
let year = year.clamp(-9999, 9999);
let month = month.clamp(1, 12);
Self { year, month }
}
pub fn year(self) -> i16 {
self.year
}
pub fn month(self) -> i8 {
self.month
}
pub fn first_day(self) -> Date {
Date::constant(self.year, self.month, 1)
}
pub fn last_day(self) -> Date {
self.first_day().last_of_month()
}
pub fn from_date(d: Date) -> Self {
Self {
year: d.year(),
month: d.month(),
}
}
pub fn next_month(self) -> Self {
if self.month == 12 {
Self::new(self.year.saturating_add(1), 1)
} else {
Self::new(self.year, self.month + 1)
}
}
pub fn prev_month(self) -> Self {
if self.month == 1 {
Self::new(self.year.saturating_sub(1), 12)
} else {
Self::new(self.year, self.month - 1)
}
}
pub fn offset_months(self, n: i32) -> Self {
let total = self.year as i32 * 12 + (self.month as i32 - 1) + n;
let year = (total.div_euclid(12)).clamp(-9999, 9999) as i16;
let month = (total.rem_euclid(12) + 1) as i8;
Self::new(year, month)
}
}
pub fn weekday_from_monday_zero(offset: i8) -> Weekday {
Weekday::from_monday_zero_offset(offset.rem_euclid(7))
.expect("monday-zero offset already in 0..=6")
}
pub fn today_local() -> Date {
jiff::Zoned::now().date()
}