DocumentsPersonal
Time and Duration Utilities
Time and Duration Utilities
Type
Topic
Status
Published
Created
Jul 8, 2026
Updated
Jul 8, 2026

Time and Duration Utilities#

OpenDAL centralizes all timestamp and duration handling in core/src/raw/time.rs . This module provides a Timestamp wrapper type and re-exports Instant, SystemTime, and Duration in a platform-aware way, ensuring the rest of the codebase never imports std::time directly or references the underlying time library.

The module reached its current form through three migrations: chrono → jiff (Oct 2025, breaking), jiff → Timestamp wrapper (Oct 2025, abstraction), and wasm32 support via the web-time crate (Dec 2025, extended Apr 2026).

core/src/raw/time.rs — The Centralized Time Module#

Entry point: core/src/raw/time.rs (introduced in PR #6650), exported via core/src/raw/mod.rs.

Timestamp wrapper#

Timestamp wraps jiff::Timestamp and is the canonical timestamp type across OpenDAL. It is exported as opendal::raw::Timestamp.

Key methods :

MethodDescription
Timestamp::now()Current UTC time
Timestamp::from_millisecond(ms: i64)Construct from Unix milliseconds
Timestamp::from_second(s: i64)Construct from Unix seconds
Timestamp::as_millisecond()Milliseconds since Unix epoch
Timestamp::format_http_date()RFC 9110 HTTP date string (for If-Modified-Since etc.)
Timestamp::format_rfc3339()RFC 3339 string
Timestamp::format_iso8601()ISO 8601 string

Conversion traits implemented: From, TryFrom, FromStr. Parsing via str.parse::<Timestamp>() replaces the old parse_datetime_from_rfc3339() helper .

Public surface#

Metadata::last_modified() returns Option<Timestamp> . Read/write/stat options also use Timestamp for if_modified_since / if_unmodified_since fields.

Platform-aware Instant / SystemTime / Duration#

The module also re-exports Instant, SystemTime, and Duration so consuming code never imports std::time directly :

// wasm32-unknown-unknown
pub use web_time::{Duration, Instant, SystemTime};

// all other targets
pub use std::time::{Duration, Instant, SystemTime};

All layers (retry, timeout, metrics, tail-cut) and services import these types via crate::raw::* instead of std::time .

wasm32 Cross-Platform Support#

std::time::Instant and std::time::SystemTime do not exist in browser WASM environments. PR #6852 resolved this by making time.rs the single gating point: re-exports switch to the web-time crate for wasm32 targets .

PR #7360 subsequently narrowed the gate from cfg(target_arch = "wasm32") to cfg(all(target_arch = "wasm32", target_os = "unknown")), restricting web-time to browser WASM (wasm32-unknown-unknown) only and leaving WASI and other wasm targets unaffected . The web-time dependency is declared under [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] in core/Cargo.toml .

Timestamp conversions to/from SystemTime use web_time::SystemTimeExt::{from_std, to_std} on wasm32-unknown-unknown, and direct std::time::SystemTime conversions everywhere else .

Migration History#

DatePRChange
Pre-Oct 2025core/src/raw/chrono_util.rs with chrono 0.4.x; public API exposed DateTime<Utc>
Oct 10, 2025#6643Breaking: replaced chrono with jiff across 103 files; intermediate jiff_util.rs module
Oct 14, 2025#6650Introduced Timestamp wrapper in time.rs; removed jiff_util.rs; Metadata::last_modified() now returns Option<Timestamp>
Dec 1, 2025#6852Added web-time re-exports for Instant/SystemTime on wasm32; removes all direct std::time imports across layers and services
Apr 8, 2026#7360Narrowed wasm32 gate to wasm32-unknown-unknown only, fixing unintended WASI breakage

Why jiff over chrono?#

PR #6643 described the migration as replacing the legacy chrono crate with the newer jiff. The Timestamp wrapper was added in PR #6650 immediately afterward to prevent jiff::Timestamp from leaking into the public API, keeping the underlying library swappable without further breaking changes.

Language Binding Strategy#

Each language binding converts Timestamp at its own boundary rather than depending on jiff directly :

  • C: calls as_millisecond() for an integer representation
  • Java: uses Timestamp::from_second(s) and into_inner().as_second() / subsec_nanosecond() for java.time.Instant construction
  • Node.js: parses if_modified_since / if_unmodified_since via str.parse::<Timestamp>()
  • Python: a custom PyO3 wrapper implements IntoPyObject / FromPyObject for automatic datetimeTimestamp conversion; the core crate has no PyO3 dependency