impl PartialOrd for DateTime

This commit is contained in:
Nathan Fisher 2023-06-10 01:13:52 -04:00
parent 931d384e05
commit 2bf74ecbab

View file

@ -1,5 +1,5 @@
//! A container representing a moment in ISO-8601 format Time
use std::{fmt, str::FromStr};
use std::{cmp::Ordering, fmt, str::FromStr};
mod error;
mod parser;
@ -7,8 +7,9 @@ pub use {error::Error, parser::Parser};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use x509_parser::der_parser::ber::ber_read_element_header;
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum Sign {
Positive,
@ -36,7 +37,7 @@ impl TryFrom<char> for Sign {
}
}
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct Offset {
pub sign: Sign,
@ -54,7 +55,7 @@ impl fmt::Display for Offset {
}
}
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum TimeZone {
UTC,
@ -70,7 +71,7 @@ impl fmt::Display for TimeZone {
}
}
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct DateTime {
pub year: u32,
@ -110,6 +111,52 @@ impl fmt::Display for DateTime {
}
}
impl PartialOrd for DateTime {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
let a = self.normalize()?;
let b = other.normalize()?;
(a.year, a.month, a.day, a.hour, a.minute, a.second)
.partial_cmp(&(b.year, b.month, b.day, b.hour, b.minute, b.second))
}
}
impl DateTime {
pub fn normalize(&self) -> Option<Self> {
if self.tz == Some(TimeZone::UTC) {
Some(*self)
} else {
if let Some(TimeZone::Offset(tz)) = self.tz {
let hour = if let Some(hour) = self.hour {
match tz.sign {
Sign::Positive => Some(hour + tz.hours),
Sign::Negative => Some(hour - tz.hours),
}
} else {
None
};
let minute = 'blk: {
if let Some(minutes) = self.minute {
if let Some(o) = tz.minutes {
match tz.sign {
Sign::Positive => break 'blk Some(minutes + o),
Sign::Negative => break 'blk Some(minutes - o),
}
}
}
None
};
Some(DateTime {
hour,
minute,
..*self
})
} else {
None
}
}
}
}
#[cfg(test)]
mod test {
use super::*;