Expand description
ZIP file timestamp handling
Datetimes for ZIP files come in two flavors: UTC and local time. It is not possible for the local time zone to be encoded in the ZIP format, so converting between the two requires assuming that UTC is the local time.
When reading a ZIP file, ZipDateTimeKind
will provide information about
the timestamp’s original time zone (UTC and local time)
However, when writing a ZIP file, only a UtcDateTime
is supported.
§Example: Copying Modification Times
This example shows how to read a ZIP file and create a new one while preserving modification times:
use rawzip::{ZipArchive, ZipArchiveWriter, ZipDataWriter};
use rawzip::time::{ZipDateTimeKind, UtcDateTime};
use std::io::Write;
// Read a test ZIP file with timestamps
let input_data = include_bytes!("../assets/time-go.zip");
let input_archive = ZipArchive::from_slice(input_data).unwrap();
// Create output archive
let mut output_data = Vec::new();
let mut output_archive = ZipArchiveWriter::new(&mut output_data);
// Copy each entry with its modification time
let mut entries = input_archive.entries();
while let Ok(Some(entry)) = entries.next_entry() {
let name = entry.file_path().try_normalize().unwrap().as_ref().to_string();
let modification_time = entry.last_modified();
let utc_time = match modification_time {
ZipDateTimeKind::Utc(utc_time) => utc_time,
ZipDateTimeKind::Local(local_time) => {
// Convert local time to UTC by reinterpreting the components
// This treats the local time as if it were UTC
UtcDateTime::from_components(
local_time.year(),
local_time.month(),
local_time.day(),
local_time.hour(),
local_time.minute(),
local_time.second(),
local_time.nanosecond()
).unwrap()
}
};
if !entry.is_dir() {
// Copy file with preserved modification time
let (mut entry, config) = output_archive.new_file(&name)
.last_modified(utc_time)
.start()
.unwrap();
let mut writer = config.wrap(&mut entry);
writer.write_all(b"example data").unwrap();
let (_, descriptor) = writer.finish().unwrap();
entry.finish(descriptor).unwrap();
} else {
// Copy directory with preserved modification time
output_archive.new_dir(&name)
.last_modified(utc_time)
.create()
.unwrap();
}
}
output_archive.finish().unwrap();
// Verify the output archive preserves timestamps
let output_archive = ZipArchive::from_slice(&output_data).unwrap();
assert!(output_archive.entries_hint() > 0, "Output should contain entries");
// Verify at least one entry has a UTC timestamp
let mut output_entries = output_archive.entries();
let mut has_utc_timestamp = false;
while let Ok(Some(entry)) = output_entries.next_entry() {
if matches!(entry.last_modified(), ZipDateTimeKind::Utc(_)) {
has_utc_timestamp = true;
break;
}
}
assert!(has_utc_timestamp, "Output should contain UTC timestamps");
Structs§
- DosDate
Time - Represents an MS-DOS timestamp with 2-second precision.
- Local
- Marker type for Local timezone
- Utc
- Marker type for UTC timezone
- ZipDate
Time - Represents a timestamp found in a ZIP file
Enums§
- Time
Zone - Represents the time zone of a timestamp.
- ZipDate
Time Kind - Enum for timestamp parsing results that can be either UTC or Local
Traits§
- Time
Zone Marker - Trait for timezone markers
Type Aliases§
- Local
Date Time - Type alias for Local timestamps
- UtcDate
Time - Type alias for UTC timestamps