Real Epoch Converter logo realepochconverter
programming guide

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.

Rust
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.

Rust
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.

Rust
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; Tz is 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() truncatesas_secs() on a sub-second Duration returns 0; use as_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 time crate (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

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.

Copied