From 630ca3fa0f23a469f0c1c77feb24979d57c0e4aa Mon Sep 17 00:00:00 2001
From: Chris Hennick <hennickc@amazon.com>
Date: Tue, 30 May 2023 10:06:20 -0700
Subject: [PATCH] Bug fixes for chrono integration

---
 README.md     |  3 +--
 src/result.rs |  8 ++++++++
 src/types.rs  | 13 +++++--------
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 566fb09e..38b93134 100644
--- a/README.md
+++ b/README.md
@@ -54,8 +54,7 @@ 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`.
+* `chrono`: Enables converting last-modified `zip_next::DateTime` to and from `chrono::NaiveDateTime`.
 * `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/result.rs b/src/result.rs
index 749f3354..0c4776eb 100644
--- a/src/result.rs
+++ b/src/result.rs
@@ -4,6 +4,7 @@ use std::error::Error;
 use std::fmt;
 use std::io;
 use std::io::IntoInnerError;
+use std::num::TryFromIntError;
 
 /// Generic result type with ZipError as its error variant
 pub type ZipResult<T> = Result<T, ZipError>;
@@ -93,6 +94,13 @@ impl From<ZipError> for io::Error {
 #[derive(Debug)]
 pub struct DateTimeRangeError;
 
+// TryFromIntError is also an out-of-range error.
+impl From<TryFromIntError> for DateTimeRangeError {
+    fn from(_value: TryFromIntError) -> Self {
+        DateTimeRangeError
+    }
+}
+
 impl fmt::Display for DateTimeRangeError {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(
diff --git a/src/types.rs b/src/types.rs
index 3ab8a02f..86c41e13 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -120,13 +120,10 @@ impl arbitrary::Arbitrary<'_> for DateTime {
 
 #[cfg(feature = "chrono")]
 #[allow(clippy::result_unit_err)]
-impl<T> TryFrom<T> for DateTime
-where
-    T: Datelike + Timelike,
-{
-    type Error = ();
+impl TryFrom<NaiveDateTime> for DateTime {
+    type Error = DateTimeRangeError;
 
-    fn try_from(value: T) -> Result<Self, Self::Error> {
+    fn try_from(value: NaiveDateTime) -> Result<Self, Self::Error> {
         Ok(DateTime::from_date_and_time(
             value.year().try_into()?,
             value.month().try_into()?,
@@ -202,7 +199,7 @@ impl DateTime {
         hour: u8,
         minute: u8,
         second: u8,
-    ) -> Result<DateTime, ()> {
+    ) -> Result<DateTime, DateTimeRangeError> {
         if (1980..=2107).contains(&year)
             && (1..=12).contains(&month)
             && (1..=31).contains(&day)
@@ -219,7 +216,7 @@ impl DateTime {
                 second,
             })
         } else {
-            Err(())
+            Err(DateTimeRangeError)
         }
     }