152

How can I get the current time in milliseconds like I can in Java?

System.currentTimeMillis()
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Incerteza
  • 32,326
  • 47
  • 154
  • 261

8 Answers8

225

Since Rust 1.8, you do not need to use a crate. Instead, you can use SystemTime and UNIX_EPOCH:

use std::time::{SystemTime, UNIX_EPOCH};

fn main() {
    let start = SystemTime::now();
    let since_the_epoch = start
        .duration_since(UNIX_EPOCH)
        .expect("Time went backwards");
    println!("{:?}", since_the_epoch);
}

If you need exactly milliseconds, you can convert the Duration.

Rust 1.33

let in_ms = since_the_epoch.as_millis();

Rust 1.27

let in_ms = since_the_epoch.as_secs() as u128 * 1000 + 
            since_the_epoch.subsec_millis() as u128;

Rust 1.8

let in_ms = since_the_epoch.as_secs() * 1000 +
            since_the_epoch.subsec_nanos() as u64 / 1_000_000;
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 6
    Why systemtime rather than instant? – Andy Hayden Jan 31 '19 at 16:32
  • 5
    @AndyHayden you may wish to re-read the [documentation for `Instant`](https://doc.rust-lang.org/std/time/struct.Instant.html): *There is no method to get "the number of seconds" from an instant. Instead, it only allows measuring the duration between two instants (or comparing two instants).* – Shepmaster Feb 01 '19 at 01:11
  • Does this get seconds since Epoch, in UTC time, or would you still need to add/subtract the timezone to get an "absolute" time? – Timmmm May 24 '21 at 09:42
  • Ah according to the docs `UNIX_EPOCH` is 1970.000, UTC. So I think you don't need to consider the timezone. – Timmmm May 24 '21 at 09:44
  • is there a 64bit version or do we have to cast? – Dominic Feb 20 '22 at 00:33
  • 1
    @Dominic [How do I convert between numeric types safely and idiomatically?](https://stackoverflow.com/q/28273169/155423). Presumably durations can represent a longer span of time than 64-bits would allow. – Shepmaster Feb 20 '22 at 02:04
  • Seems quite extreme though since I don’t think my program needs to live beyond the year 229 billion – Dominic Feb 20 '22 at 11:47
  • Just started with Rust, and it would be kind if you could share some more experience. Does everybody needs to create own function which return _current_ timestamp, or do developers _repeat themselves_ each place where the timestamp is needed. Or is it such a rare need to have a current timestamp so that it's a fine approach to compare with epoch (and handle error)? – Sergey Kaunov Sep 20 '22 at 15:42
  • 1
    @SergeyKaunov I'd expect that most people create a function, yes, but the important thing is likely *how* the error is handled. Some people may prefer a default value, some will raise a `panic!`, and others may propagate the error. There's no one-size-fits-all solution. – Shepmaster Sep 20 '22 at 15:48
  • Yeah, of course. I'm not bragging just try to internalize this approach which alienating at first sight: it takes so much just to have a current timestamp as a number. \ \ It's totally cute that it's possible to fine tune details, but overwhelms when there's no need for them... Sorry, I'm just on the learning curve. =)) – Sergey Kaunov Sep 20 '22 at 15:51
57

If you just want to do simple timings with the milliseconds, you can use std::time::Instant like this:

use std::time::Instant;

fn main() {
    let start = Instant::now();

    // do stuff

    let elapsed = start.elapsed();

    // Debug format
    println!("Debug: {:?}", elapsed); 

    // Format as milliseconds rounded down
    // Since Rust 1.33:
    println!("Millis: {} ms", elapsed.as_millis());

    // Before Rust 1.33:
    println!("Millis: {} ms",
             (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64);
}

Output:

Debug: 10.93993ms
Millis: 10 ms
Millis: 10 ms
robinst
  • 30,027
  • 10
  • 102
  • 108
21

You can use the time crate:

extern crate time;

fn main() {
    println!("{}", time::now());
}

It returns a Tm which you can get whatever precision you want.

Quonux
  • 2,975
  • 1
  • 24
  • 32
Steve Klabnik
  • 14,521
  • 4
  • 58
  • 99
  • 2
    The `precise_time_...` functions from that crate are also relevant, if one just wishes to measure relative times. – huon Oct 27 '14 at 21:42
  • how do I get milliseconds? – Incerteza Oct 30 '14 at 01:28
  • 1
    You have to use `time::now_utc()` or `time::get_time()` since Java's System.currentTimeMillis() returns UTC time. I would write `let timespec = time::get_time(); let mills = timespec.sec + timespec.nsec as i64 / 1000 / 1000;` – Nándor Krácser Nov 23 '14 at 18:44
  • 1
    time::precise_time_ns() and time::precise_time_s() – tyoc213 Mar 19 '16 at 20:44
  • 7
    This crate is now deprecated. Use `chrono` crate instead. – Ondrej Slinták Aug 12 '19 at 14:04
  • The deprecation message is in the notes, but not the `readme` in case that confused anyone else: https://docs.rs/crate/time/0.1.42 – Rokit Dec 05 '19 at 17:04
  • 2
    I love how in every single programming language libs related to time are constantly being deprecated. – LLL Aug 28 '20 at 10:50
20

I've found a clear solution with chrono in coinnect:

use chrono::prelude::*;

pub fn get_unix_timestamp_ms() -> i64 {
    let now = Utc::now();
    now.timestamp_millis()
}

pub fn get_unix_timestamp_us() -> i64 {
    let now = Utc::now();
    now.timestamp_nanos()
}
LINE
  • 3
  • 4
DenisKolodin
  • 13,501
  • 3
  • 62
  • 65
11

As @Shepmaster mentioned, this is the equivalent of Java's System.currentTimeMillis() in Rust.

use std::time::{SystemTime, UNIX_EPOCH};

fn get_epoch_ms() -> u128 {
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_millis()
}
Tamas Foldi
  • 487
  • 4
  • 8
  • If you want more precision, this seems to work (returning fractional milliseconds): `SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs_f64() * 1000f64` – Venryx Mar 29 '22 at 22:31
7
extern crate time;

fn timestamp() -> f64 {
    let timespec = time::get_time();
    // 1459440009.113178
    let mills: f64 = timespec.sec as f64 + (timespec.nsec as f64 / 1000.0 / 1000.0 / 1000.0);
    mills
}

fn main() {
    let ts = timestamp();
    println!("Time Stamp: {:?}", ts);
}

Rust Playground

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Zijun Luo
  • 79
  • 1
  • 2
5

System.currentTimeMillis() in Java returns the difference in milliseconds between the current time and midnight, January 1, 1970.

In Rust we have time::get_time() which returns a Timespec with the current time as seconds and the offset in nanoseconds since midnight, January 1, 1970.

Example (using Rust 1.13):

extern crate time; //Time library

fn main() {
    //Get current time
    let current_time = time::get_time();

    //Print results
    println!("Time in seconds {}\nOffset in nanoseconds {}",
             current_time.sec, 
             current_time.nsec);

    //Calculate milliseconds
    let milliseconds = (current_time.sec as i64 * 1000) + 
                       (current_time.nsec as i64 / 1000 / 1000);

    println!("System.currentTimeMillis(): {}", milliseconds);
}

Reference: Time crate, System.currentTimeMillis()

josehzz
  • 395
  • 4
  • 6
2

There seems to be a simple one-liner that yields a u128, which is pretty close to what a java long is.

let timestamp = std::time::UNIX_EPOCH.elapsed().unwrap().as_millis()

The docs do warn about clock drifting related to SystemTime objects, but I think this does not apply here, given we're checking against a point in time way back.

dpereira
  • 56
  • 6