Rust Unix Timestamp: SystemTime, chrono & the epoch accessor
Rust's standard library gives you SystemTime — an opaque clock reading you convert to an epoch with one unwrap. The chrono crate then types the timezone right into the type system: DateTime<Utc> is aware by construction, and naivety is an explicit, separate type.
Get the current Unix timestamp (stdlib)
SystemTime::now() minus UNIX_EPOCH yields a
Duration; as_secs() gives whole seconds and
as_millis() milliseconds. The unwrap() only panics on pre-1970
clocks — practically never, but the option type forces you to decide.
use std::time::{SystemTime, UNIX_EPOCH};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("System clock before 1970");
println!("{}", now.as_secs()); // 1767225600
println!("{}", now.as_millis()); // 1767225600123
println!("{}", now.as_nanos()); // nanoseconds
Convert a timestamp to a date (chrono)
DateTime::from_timestamp(sec, nsec) returns
Option<DateTime<Utc>> (None outside the supported range —
unwrap only after validating input). To
display in another zone, call .with_timezone(&FixedOffset::east_opt(19800).unwrap())
or use a named zone from chrono-tz.
use chrono::{DateTime, Utc, FixedOffset};
let dt: DateTime<Utc> = DateTime::from_timestamp(1767225600, 0).unwrap();
println!("{}", dt.to_rfc3339()); // 2026-01-01T00:00:00+00:00
let ist_offset = FixedOffset::east_opt(5 * 3600 + 1800).unwrap();
println!("{}", dt.with_timezone(&ist_offset)); // 2026-01-01 05:30:00 +05:30
Convert a date back to a timestamp
Only zone-aware types have a real epoch: DateTime<Utc> exposes
timestamp() (seconds as f64) and timestamp_millis(). A
NaiveDateTime needs and_utc() (or
and_local_timezone() for a named zone) first.
use chrono::{NaiveDate, Utc, TimeZone};
let naive = NaiveDate::from_ymd_opt(2026, 1, 1).unwrap().and_hms_opt(0, 0, 0).unwrap();
naive.and_utc().timestamp(); // 1767225600.0 (interpreted as UTC)
// If that wall-clock time was recorded in IST, pin it to IST first:
use chrono::FixedOffset;
let ist = FixedOffset::east_opt(5 * 3600 + 1800).unwrap();
ist.from_local_datetime(&naive).unwrap().timestamp(); // 1767220200.0
Naive vs aware: encoded in the type
- DateTime<Tz> — zone-aware;
Tzis part of the type (Utc,FixedOffset,Local, or a chrono-tz zone). - NaiveDateTime — explicitly naive; you cannot call
timestamp()on it, which turns the classic bug into a compile error. - Rule: carry
DateTime<Utc>internally, convert to a display zone only at the edge.
Native precision: nanoseconds
SystemTime has nanosecond resolution (as limited by the OS clock, typically
microseconds on Linux), chrono represents sub-second parts as Nanoseconds
internally, and timestamp_nanos_opt() exposes the full epoch in ns as an
Option<i64> (range-checked).
Common pitfalls
- duration_since panics — it returns a Result; pre-1970 systems are the only failure, but don't skip the unwrap decision.
- as_secs() truncates —
as_secs()on a sub-second Duration returns 0; useas_millis()when you need the fraction. - from_timestamp returns Option — invalid or out-of-range input yields
None; validate before unwrapping. - chrono vs time crate — the
timecrate (OffsetDateTime) is a valid alternative with the same aware/naive split.
Try it live
Cross-check values in the epoch converter, or copy the current timestamp from the Rust snippet tab on the homepage.
First published · Last reviewed · Maintained and developed by the Real Epoch Converter team · [email protected] · Contact · Methodology
Sources & references
Unix time in every language
JavaScript · Python · PHP · SQL · Go · Java · C# · Rust · C++ · PowerShell
Prefer the point-and-click version? The epoch time converter on the home page handles seconds, milliseconds, and microseconds in any timezone — every snippet on this page produces the same value that tool shows.