@@ -910,6 +910,7 @@ impl<R: Read + Seek> ZipArchive<R> {
910
910
}
911
911
let mut file = self . by_index ( i) ?;
912
912
let mut outfile = fs:: File :: create ( & outpath) ?;
913
+
913
914
io:: copy ( & mut file, & mut outfile) ?;
914
915
#[ cfg( unix) ]
915
916
{
@@ -918,6 +919,15 @@ impl<R: Read + Seek> ZipArchive<R> {
918
919
files_by_unix_mode. push ( ( outpath. clone ( ) , mode) ) ;
919
920
}
920
921
}
922
+ #[ cfg( feature = "chrono" ) ]
923
+ {
924
+ // Set original timestamp.
925
+ if let Some ( last_modified) = file. last_modified ( ) {
926
+ if let Some ( t) = datetime_to_systemtime ( & last_modified) {
927
+ outfile. set_modified ( t) ?;
928
+ }
929
+ }
930
+ }
921
931
}
922
932
#[ cfg( unix) ]
923
933
{
@@ -2024,6 +2034,35 @@ pub fn root_dir_common_filter(path: &Path) -> bool {
2024
2034
true
2025
2035
}
2026
2036
2037
+ #[ cfg( feature = "chrono" ) ]
2038
+ /// Generate a `SystemTime` from a `DateTime`.
2039
+ fn datetime_to_systemtime ( datetime : & DateTime ) -> Option < std:: time:: SystemTime > {
2040
+ if let Some ( t) = generate_chrono_datetime ( datetime) {
2041
+ let time = chrono:: DateTime :: < chrono:: Utc > :: from_naive_utc_and_offset ( t, chrono:: Utc ) ;
2042
+ return Some ( time. into ( ) ) ;
2043
+ }
2044
+ None
2045
+ }
2046
+
2047
+ #[ cfg( feature = "chrono" ) ]
2048
+ /// Generate a `NaiveDateTime` from a `DateTime`.
2049
+ fn generate_chrono_datetime ( datetime : & DateTime ) -> Option < chrono:: NaiveDateTime > {
2050
+ if let Some ( d) = chrono:: NaiveDate :: from_ymd_opt (
2051
+ datetime. year ( ) . into ( ) ,
2052
+ datetime. month ( ) . into ( ) ,
2053
+ datetime. day ( ) . into ( ) ,
2054
+ ) {
2055
+ if let Some ( d) = d. and_hms_opt (
2056
+ datetime. hour ( ) . into ( ) ,
2057
+ datetime. minute ( ) . into ( ) ,
2058
+ datetime. second ( ) . into ( ) ,
2059
+ ) {
2060
+ return Some ( d) ;
2061
+ }
2062
+ }
2063
+ None
2064
+ }
2065
+
2027
2066
#[ cfg( test) ]
2028
2067
mod test {
2029
2068
use crate :: result:: ZipResult ;
0 commit comments