diff --git a/CHANGELOG.md b/CHANGELOG.md index ebf0d55f..a0d7010b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -196,4 +196,5 @@ ### Added - - `zlib-ng` for fast Deflate compression. This is now the default for compression levels 0-9. \ No newline at end of file + - `zlib-ng` for fast Deflate compression. This is now the default for compression levels 0-9. + - `chrono` to convert zip_next::DateTime to and from chrono::NaiveDateTime \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 63b0c17d..84204c3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ edition = "2021" aes = { version = "0.8.2", optional = true } byteorder = "1.4.3" bzip2 = { version = "0.4.4", optional = true } +chrono = { version = "0.4.25", optional = true } constant_time_eq = { version = "0.2.5", optional = true } crc32fast = "1.3.2" flate2 = { version = "1.0.26", default-features = false, optional = true } @@ -40,6 +41,7 @@ time = { version = "0.3.21", features = ["formatting", "macros"] } [features] aes-crypto = [ "aes", "constant_time_eq", "hmac", "pbkdf2", "sha1" ] +chrono = ["chrono/default"] deflate = ["flate2/rust_backend"] deflate-miniz = ["flate2/default"] deflate-zlib = ["flate2/zlib"] diff --git a/README.md b/README.md index 9c747911..566fb09e 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ The features available are: is the most effective `deflate` implementation available. * `bzip2`: Enables the BZip2 compression algorithm. * `time`: Enables features using the [time](https://github.com/rust-lang-deprecated/time) crate. +* `chrono`: Enables converting last-modified `zip_next::DateTime` to and from `chrono::NaiveDateTime` and from + `chrono::DateTime`. * `zstd`: Enables the Zstandard compression algorithm. By default `aes-crypto`, `deflate`, `deflate-zlib-ng`, `deflate-zopfli`, `bzip2`, `time` and `zstd` are enabled. diff --git a/src/types.rs b/src/types.rs index 661cff4e..3ab8a02f 100644 --- a/src/types.rs +++ b/src/types.rs @@ -3,6 +3,8 @@ use path::{Component, Path, PathBuf}; use std::path; use std::sync::Arc; +#[cfg(feature = "chrono")] +use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike}; #[cfg(not(any( all(target_arch = "arm", target_pointer_width = "32"), target_arch = "mips", @@ -116,6 +118,39 @@ impl arbitrary::Arbitrary<'_> for DateTime { } } +#[cfg(feature = "chrono")] +#[allow(clippy::result_unit_err)] +impl TryFrom for DateTime +where + T: Datelike + Timelike, +{ + type Error = (); + + fn try_from(value: T) -> Result { + Ok(DateTime::from_date_and_time( + value.year().try_into()?, + value.month().try_into()?, + value.day().try_into()?, + value.hour().try_into()?, + value.minute().try_into()?, + value.second().try_into()?, + )?) + } +} + +#[cfg(feature = "chrono")] +#[allow(clippy::result_unit_err)] +impl TryInto for DateTime { + type Error = (); + + fn try_into(self) -> Result { + Ok(NaiveDateTime::new( + NaiveDate::from_ymd_opt(self.year.into(), self.month.into(), self.day.into())?, + NaiveTime::from_hms_opt(self.hour.into(), self.minute.into(), self.second.into())?, + )) + } +} + impl Default for DateTime { /// Constructs an 'default' datetime of 1980-01-01 00:00:00 fn default() -> DateTime {