Skip to content
Select theme

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):

Terminal window
cargo run -q
1793189477

The 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:

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:

second time provided was later than self

A 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:

1793189477

The Duration from duration_since carries nanosecond precision, and gives it up at whatever coarseness you ask:

1793189477
1793189477139
1793189477139297
1793189477139297000

All 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:

Instant { tv_sec: 14008, tv_nsec: 604324500 }
52 ms
at least 50 ms: true

The 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).
  • Instant versus SystemTime for measuring durations gets its own article later in this chapter.
  • Working with dates and time — the rest of the chapter.