use std::fmt;
use std::ops::Sub;
use std::str::FromStr;
use crate::{DateTime, Duration, ParseDateTimeError};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Date {
year: i32,
month: u8,
day: u8,
}
impl Date {
#[inline(always)]
pub(crate) const fn from_validated(year: i32, month: u8, day: u8) -> Self {
Self { year, month, day }
}
#[inline(always)]
pub fn now() -> Self {
DateTime::now().date()
}
#[inline(always)]
pub fn parse(value: &str) -> Result<Self, ParseDateTimeError> {
DateTime::parse(value).map(|date_time| date_time.date())
}
#[inline(always)]
pub fn add_duration(self, duration: Duration) -> DateTime {
DateTime::new(self.year, self.month, self.day, 0, 0, 0, 0)
.expect("date fields must be valid")
.add_duration(duration)
}
#[inline(always)]
pub fn sub_duration(self, duration: Duration) -> DateTime {
DateTime::new(self.year, self.month, self.day, 0, 0, 0, 0)
.expect("date fields must be valid")
.sub_duration(duration)
}
#[inline(always)]
pub fn year(self) -> i32 {
self.year
}
#[inline(always)]
pub fn month(self) -> u8 {
self.month
}
#[inline(always)]
pub fn day(self) -> u8 {
self.day
}
}
impl Sub for Date {
type Output = Duration;
#[inline(always)]
fn sub(self, rhs: Self) -> Self::Output {
let left = DateTime::new(self.year, self.month, self.day, 0, 0, 0, 0)
.expect("date fields must be valid");
let right = DateTime::new(rhs.year, rhs.month, rhs.day, 0, 0, 0, 0)
.expect("date fields must be valid");
left - right
}
}
impl fmt::Display for Date {
#[inline(always)]
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"{:04}-{:02}-{:02}",
self.year, self.month, self.day
)
}
}
impl FromStr for Date {
type Err = ParseDateTimeError;
#[inline(always)]
fn from_str(value: &str) -> Result<Self, Self::Err> {
Self::parse(value)
}
}