#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Date {
pub year: i32,
pub month: u32,
pub day: u32,
}
impl Date {
pub fn new(year: i32, month: u32, day: u32) -> Self {
Self { year, month, day }
}
pub fn today() -> Self {
Self::new(2025, 1, 1)
}
pub fn is_valid(&self) -> bool {
self.month >= 1
&& self.month <= 12
&& self.day >= 1
&& self.day <= super::utils::days_in_month(self.year, self.month)
}
pub fn weekday(&self) -> u32 {
let first = super::utils::first_day_of_month(self.year, self.month);
(first + self.day - 1) % 7
}
pub fn prev_day(&self) -> Self {
if self.day > 1 {
Self::new(self.year, self.month, self.day - 1)
} else if self.month > 1 {
let prev_month = self.month - 1;
let days = super::utils::days_in_month(self.year, prev_month);
Self::new(self.year, prev_month, days)
} else {
Self::new(self.year - 1, 12, 31)
}
}
pub fn next_day(&self) -> Self {
let days = super::utils::days_in_month(self.year, self.month);
if self.day < days {
Self::new(self.year, self.month, self.day + 1)
} else if self.month < 12 {
Self::new(self.year, self.month + 1, 1)
} else {
Self::new(self.year + 1, 1, 1)
}
}
pub fn subtract_days(&self, n: u32) -> Self {
let mut result = *self;
for _ in 0..n {
result = result.prev_day();
}
result
}
pub fn add_days(&self, n: u32) -> Self {
let mut result = *self;
for _ in 0..n {
result = result.next_day();
}
result
}
}
impl Default for Date {
fn default() -> Self {
Self::new(2025, 1, 1)
}
}