How to get the current time
Short answer: SystemTime::now() gives you the current wall-clock time. It is an opaque point in time — to turn it into a number you can store or send over the network, measure the distance to the Unix epoch with duration_since(UNIX_EPOCH):
use std::time::{SystemTime, UNIX_EPOCH};
fn main() { let now = SystemTime::now(); let secs = now .duration_since(UNIX_EPOCH) .expect("system clock before 1970?") .as_secs(); println!("{secs}");}cargo run -q1793189477The number is seconds since 1970-01-01 00:00:00 UTC, and yours will be different — it is whatever the clock read when the program ran. This is the same Unix timestamp every other language and database means, so it is the right thing to store when you need to remember when something happened.
From a fresh project — cargo new clock-demo, then replace src/main.rs with each block below.
What you get back is an opaque point in time
Section titled “What you get back is an opaque point in time”SystemTime is not a number, a date, or a calendar. The only thing you can do with one directly is print its debug representation:
use std::time::SystemTime;
fn main() { let now = SystemTime::now(); println!("{now:?}");}SystemTime { tv_sec: 1793189477, tv_nsec: 139297000 }Those fields are the operating system’s clock reading (seconds and nanoseconds since the epoch, on this platform), not a public interface — code that reaches into tv_sec is one platform away from not compiling. Everything useful goes through duration_since, which returns a Duration you can convert freely.
And there is no formatting here on purpose: turning a SystemTime into 2026-10-28 20:11:17 needs a calendar — months have names, days have lengths, timezones exist — and the standard library does not do calendars. That is the next article’s subject, and it needs a crate.
duration_since returns a Result, because the clock can go backwards
Section titled “duration_since returns a Result, because the clock can go backwards”now.duration_since(earlier) means “how much later is now than earlier”. It returns a Result rather than a plain Duration because the wall clock is not guaranteed to move forward: NTP corrections, a manual timezone change, or a VM resuming from a snapshot can all step it backwards. The error case is easy to provoke by asking about a time that has not happened yet:
use std::time::{Duration, SystemTime, UNIX_EPOCH};
fn main() { let now = SystemTime::now(); let year_2096 = UNIX_EPOCH + Duration::from_secs(4_000_000_000); match now.duration_since(year_2096) { Ok(d) => println!("2096 is {d:?} away"), Err(e) => println!("{}", e), }}second time provided was later than selfA SystemTime plus a Duration is another SystemTime, which is how the example builds its 2096 timestamp. On the Err branch, e.duration() hands back the amount by which the ordering was violated — useful if you want to log it. The expect in the short answer is the honest version of “this cannot happen here”: a machine whose clock is before 1970 has worse problems than this program.
If you only need “seconds since the epoch” and are happy to treat a backwards clock as unrecoverable, this is the idiomatic one-liner:
use std::time::{SystemTime, UNIX_EPOCH};
fn main() { let secs = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_secs(); println!("{secs}");}1793189477Sub-second precision
Section titled “Sub-second precision”The Duration from duration_since carries nanosecond precision, and gives it up at whatever coarseness you ask:
use std::time::{SystemTime, UNIX_EPOCH};
fn main() { let d = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); println!("{}", d.as_secs()); println!("{}", d.as_millis()); println!("{}", d.as_micros()); println!("{}", d.as_nanos());}1793189477179318947713917931894771392971793189477139297000All four are the same instant, truncated to the unit asked for. as_millis is the unit most APIs mean when they say “timestamp in milliseconds”; it is also the one where a u64 of milliseconds comfortably outlives the species, so there is no 2038 problem in this representation. Converting these numbers back into dates is its own article later in this chapter.
Measuring elapsed time? You want Instant, not SystemTime
Section titled “Measuring elapsed time? You want Instant, not SystemTime”If what you actually want from “the current time” is how long something took, SystemTime is the wrong clock, and the compiler will not stop you. Because the wall clock can step backwards, a duration measured across such a step comes out wrong — including negative, which Duration cannot even represent.
For measuring, the standard library has a second clock, Instant, which is monotonic: it never goes backwards, because it counts from an arbitrary fixed point (on this machine, boot) rather than from the calendar:
use std::time::{Duration, Instant};
fn main() { let start = Instant::now(); println!("{start:?}"); std::thread::sleep(Duration::from_millis(50)); let took = start.elapsed(); println!("{} ms", took.as_millis()); println!("at least 50 ms: {}", took >= Duration::from_millis(50));}Instant { tv_sec: 14008, tv_nsec: 604324500 }52 msat least 50 ms: trueThe debug print is the proof: tv_sec: 14008 — about 3.9 hours, this machine’s uptime, not seconds since 1970. An Instant cannot be turned into a date and should never be stored or sent anywhere: it is only meaningful on the machine that made it, and only for a while. What it is good for is exactly the thing the wall clock is bad at — start.elapsed(), or subtracting one Instant from another, always gives the real time that passed, sleeps and clock corrections included. The sleep asked for 50 ms and the measurement came back 52 — the extra milliseconds are scheduler slack, not a clock jump.
The rule of thumb: SystemTime for when did this happen (timestamps you store or send), Instant for how long did this take (measurements you keep to yourself).
- Turning a timestamp into an actual date needs a calendar library — that is the next article’s subject (
chrono). InstantversusSystemTimefor measuring durations gets its own article later in this chapter.- Working with dates and time — the rest of the chapter.