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 Time {
hour: u8,
minute: u8,
second: u8,
millisecond: u16,
}
impl Time {
#[inline(always)]
pub(crate) const fn from_validated(hour: u8, minute: u8, second: u8, millisecond: u16) -> Self {
Self {
hour,
minute,
second,
millisecond,
}
}
#[inline(always)]
pub fn now() -> Self {
DateTime::now().time()
}
#[inline(always)]
pub fn parse(value: &str) -> Result<Self, ParseDateTimeError> {
DateTime::parse(value).map(|date_time| date_time.time())
}
#[inline(always)]
pub fn add_duration(self, duration: Duration) -> DateTime {
DateTime::new(
1970,
1,
1,
self.hour,
self.minute,
self.second,
self.millisecond,
)
.expect("time fields must be valid")
.add_duration(duration)
}
#[inline(always)]
pub fn sub_duration(self, duration: Duration) -> DateTime {
DateTime::new(
1970,
1,
1,
self.hour,
self.minute,
self.second,
self.millisecond,
)
.expect("time fields must be valid")
.sub_duration(duration)
}
#[inline(always)]
pub fn hour(self) -> u8 {
self.hour
}
#[inline(always)]
pub fn minute(self) -> u8 {
self.minute
}
#[inline(always)]
pub fn second(self) -> u8 {
self.second
}
#[inline(always)]
pub fn millisecond(self) -> u16 {
self.millisecond
}
#[inline(always)]
pub fn to_string_secs(self) -> String {
format!("{:02}:{:02}:{:02}", self.hour, self.minute, self.second)
}
#[inline(always)]
pub fn to_string_mins(self) -> String {
format!("{:02}:{:02}", self.hour, self.minute)
}
#[inline(always)]
fn as_day_millis(self) -> i64 {
self.hour as i64 * 3_600_000
+ self.minute as i64 * 60_000
+ self.second as i64 * 1_000
+ self.millisecond as i64
}
}
impl Sub for Time {
type Output = Duration;
#[inline(always)]
fn sub(self, rhs: Self) -> Self::Output {
Duration::from_millis(self.as_day_millis() - rhs.as_day_millis())
}
}
impl fmt::Display for Time {
#[inline(always)]
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"{:02}:{:02}:{:02}.{:03}",
self.hour, self.minute, self.second, self.millisecond
)
}
}
impl FromStr for Time {
type Err = ParseDateTimeError;
#[inline(always)]
fn from_str(value: &str) -> Result<Self, Self::Err> {
Self::parse(value)
}
}