std::time and the chrono crate. Working examples for every common operation — get current time, convert epoch to date, convert date to epoch, format display, parse, and handle timezones.
Rust's standard library is minimal for time — it gives you `SystemTime` but no formatting.
use std::time::{SystemTime, UNIX_EPOCH};
let secs = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
// → 1735689600 (u64)
use std::time::{SystemTime, UNIX_EPOCH};
let ms = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis();
// → 1735689600000 (u128)
For real date/time work, add the `chrono` crate. It handles timezones, formatting, parsing.
# Cargo.toml
[dependencies]
chrono = "0.4"
chrono-tz = "0.8" # for IANA timezone names
use chrono::Utc;
let now = Utc::now();
println!("{}", now.timestamp()); // seconds
println!("{}", now.timestamp_millis()); // milliseconds
Use `DateTime::from_timestamp` (chrono 0.4.31+).
use chrono::{DateTime, Utc};
let dt = DateTime::from_timestamp(1735689600, 0).unwrap();
println!("{}", dt.to_rfc3339());
// → "2025-01-01T00:00:00+00:00"
use chrono::DateTime;
use chrono_tz::America::New_York;
let dt = DateTime::from_timestamp(1735689600, 0)
.unwrap()
.with_timezone(&New_York);
println!("{}", dt);
DateTime has `.timestamp()` for seconds and `.timestamp_millis()` for ms.
use chrono::{NaiveDate, Utc, TimeZone};
let date = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let epoch = date.timestamp();
// → 1735689600
use chrono::DateTime;
let dt: DateTime<chrono::Utc> = "2025-01-01T00:00:00Z".parse().unwrap();
println!("{}", dt.timestamp());
chrono uses strftime-style format strings.
use chrono::Utc;
let now = Utc::now();
println!("{}", now.to_rfc3339());
// → "2025-01-01T12:34:56.123456789+00:00"
println!("{}", now.format("%Y-%m-%d %H:%M:%S"));
// → "2025-01-01 12:34:56"
Use `DateTime::parse_from_rfc3339` or the more flexible `NaiveDateTime::parse_from_str`.
use chrono::DateTime;
let dt = DateTime::parse_from_rfc3339("2025-01-01T00:00:00Z")?;
println!("{}", dt.timestamp());
use chrono::NaiveDateTime;
let ndt = NaiveDateTime::parse_from_str(
"2025-01-01 12:00:00",
"%Y-%m-%d %H:%M:%S"
)?;
// NaiveDateTime has no timezone; attach one before using:
use chrono::Utc;
let dt = ndt.and_utc();
Rust-specific time pitfalls.
// duration_since(UNIX_EPOCH) returns Err if the clock
// went backwards. unwrap() in production is risky:
let secs = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
// chrono distinguishes NaiveDateTime (no timezone) from
// DateTime<Tz> (with timezone). Always prefer DateTime
// for code that produces or consumes Unix timestamps.
Need to quickly check what a specific timestamp converts to? Use the main converter — paste any value and get every format back.
Working with many timestamps at once? Try the batch converter — paste a list, get a CSV or JSON file back.