From 00be854b114e44c52445fcbb184ebf42a562a802 Mon Sep 17 00:00:00 2001 From: Shun Sakai Date: Wed, 22 May 2024 10:50:18 +0900 Subject: [PATCH 1/2] feat: Implement more traits for `DateTime` Support comparing, ordering and hashing. --- src/types.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/types.rs b/src/types.rs index 269ffb0c..d6842f56 100644 --- a/src/types.rs +++ b/src/types.rs @@ -67,7 +67,7 @@ impl From for u8 { /// /// Modern zip files store more precise timestamps, which are ignored by [`crate::read::ZipArchive`], /// so keep in mind that these timestamps are unreliable. [We're working on this](https://github.com/zip-rs/zip/issues/156#issuecomment-652981904). -#[derive(Debug, Clone, Copy)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct DateTime { year: u16, month: u8, @@ -606,6 +606,49 @@ mod test { assert_eq!(dt.datepart(), 0b1111111_1100_11111); } + #[test] + fn datetime_equality() { + use super::DateTime; + + let dt = DateTime::from_date_and_time(2018, 11, 17, 10, 38, 30).unwrap(); + assert_eq!( + dt, + DateTime::from_date_and_time(2018, 11, 17, 10, 38, 30).unwrap() + ); + assert_ne!(dt, DateTime::default()); + } + + #[test] + fn datetime_order() { + use std::cmp::Ordering; + + use super::DateTime; + + let dt = DateTime::from_date_and_time(2018, 11, 17, 10, 38, 30).unwrap(); + assert_eq!( + dt.cmp(&DateTime::from_date_and_time(2018, 11, 17, 10, 38, 30).unwrap()), + Ordering::Equal + ); + // year + assert!(dt < DateTime::from_date_and_time(2019, 11, 17, 10, 38, 30).unwrap()); + assert!(dt > DateTime::from_date_and_time(2017, 11, 17, 10, 38, 30).unwrap()); + // month + assert!(dt < DateTime::from_date_and_time(2018, 12, 17, 10, 38, 30).unwrap()); + assert!(dt > DateTime::from_date_and_time(2018, 10, 17, 10, 38, 30).unwrap()); + // day + assert!(dt < DateTime::from_date_and_time(2018, 11, 18, 10, 38, 30).unwrap()); + assert!(dt > DateTime::from_date_and_time(2018, 11, 16, 10, 38, 30).unwrap()); + // hour + assert!(dt < DateTime::from_date_and_time(2018, 11, 17, 11, 38, 30).unwrap()); + assert!(dt > DateTime::from_date_and_time(2018, 11, 17, 9, 38, 30).unwrap()); + // minute + assert!(dt < DateTime::from_date_and_time(2018, 11, 17, 10, 39, 30).unwrap()); + assert!(dt > DateTime::from_date_and_time(2018, 11, 17, 10, 37, 30).unwrap()); + // second + assert!(dt < DateTime::from_date_and_time(2018, 11, 17, 10, 38, 31).unwrap()); + assert!(dt > DateTime::from_date_and_time(2018, 11, 17, 10, 38, 29).unwrap()); + } + #[test] fn datetime_bounds() { use super::DateTime; From e3b12e313e9173561027d43e9d5dd40b23f0fcc8 Mon Sep 17 00:00:00 2001 From: Shun Sakai Date: Wed, 22 May 2024 11:35:26 +0900 Subject: [PATCH 2/2] feat: Add `fmt::Display` for `DateTime` --- src/types.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/types.rs b/src/types.rs index d6842f56..7795bf4b 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,5 +1,6 @@ //! Types that specify what is contained in a ZIP. use path::{Component, Path, PathBuf}; +use std::fmt; use std::path; use std::sync::{Arc, OnceLock}; @@ -135,6 +136,17 @@ impl Default for DateTime { } } +impl fmt::Display for DateTime { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{:04}-{:02}-{:02} {:02}:{:02}:{:02}", + self.year, self.month, self.day, self.hour, self.minute, self.second + ) + } +} + impl DateTime { /// Converts an msdos (u16, u16) pair to a DateTime object pub const fn from_msdos(datepart: u16, timepart: u16) -> DateTime { @@ -649,6 +661,27 @@ mod test { assert!(dt > DateTime::from_date_and_time(2018, 11, 17, 10, 38, 29).unwrap()); } + #[test] + fn datetime_display() { + use super::DateTime; + + assert_eq!(format!("{}", DateTime::default()), "1980-01-01 00:00:00"); + assert_eq!( + format!( + "{}", + DateTime::from_date_and_time(2018, 11, 17, 10, 38, 30).unwrap() + ), + "2018-11-17 10:38:30" + ); + assert_eq!( + format!( + "{}", + DateTime::from_date_and_time(2107, 12, 31, 23, 59, 59).unwrap() + ), + "2107-12-31 23:59:59" + ); + } + #[test] fn datetime_bounds() { use super::DateTime;