Module time

Module time 

Source
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§

DosDateTime
Represents an MS-DOS timestamp with 2-second precision.
Local
Marker type for Local timezone
Utc
Marker type for UTC timezone
ZipDateTime
Represents a timestamp found in a ZIP file

Enums§

TimeZone
Represents the time zone of a timestamp.
ZipDateTimeKind
Enum for timestamp parsing results that can be either UTC or Local

Traits§

TimeZoneMarker
Trait for timezone markers

Type Aliases§

LocalDateTime
Type alias for Local timestamps
UtcDateTime
Type alias for UTC timestamps