From 2bf74ecbabb9c4ce89c24d42562837f5764b6305 Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Sat, 10 Jun 2023 01:13:52 -0400 Subject: [PATCH] impl PartialOrd for DateTime --- src/time/mod.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/time/mod.rs b/src/time/mod.rs index 04ce077..2b5cda8 100644 --- a/src/time/mod.rs +++ b/src/time/mod.rs @@ -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 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 { + 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 { + 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::*;