Как получить текущее время в миллисекундах в Rust?
Правильное решение: используем std::time::SystemTime
В Rust для получения текущего времени в миллисекундах с эпохи Unix нужно использовать модуль std::time и структуру SystemTime. В отличие от Instant, который предназначен только для измерения интервалов (и не привязан к реальному времени), SystemTime хранит момент времени, связанный с системными часами.
Вот рабочий пример:
use std::time::{SystemTime, UNIX_EPOCH};
fn main() {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("System clock is before 1970");
let millis = now.as_millis();
println!("Текущее время в миллисекундах: {}", millis);
}
Как это работает?
- SystemTime::now() — возвращает текущий момент времени, который поддерживается операционной системой.
- duration_since(UNIX_EPOCH) — вычисляет разницу между текущим моментом и началом эпохи Unix (1 января 1970 года 00:00:00 UTC). Возвращает
Result<Duration, SystemTimeError>. - expect() — обрабатывает ошибку (например, если системные часы установлены на дату до 1970 года, что маловероятно, но Rust требует явной обработки).
- as_millis() — метод структуры
Duration, возвращающий количество полных миллисекунд какu128.
Более безопасный вариант с обработкой ошибок
Если вы предпочитаете избегать паники, используйте match или unwrap_or:
use std::time::{SystemTime, UNIX_EPOCH};
fn get_unix_millis() -> u128 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or(Duration::ZERO)
.as_millis()
}
fn main() {
let millis = get_unix_millis();
println!("{}", millis);
}
Зачем нужен UNIX_EPOCH?
В Rust нет глобальной константы "сейчас". Вместо этого вы явно указываете опорную точку — начало эпохи. Это даёт гибкость: вы можете измерить разницу между любыми двумя моментами, а не только с 1970 года.
Важные замечания
- Тип возвращаемого значения:
as_millis()возвращаетu128. Если вам нуженu64(как в большинстве API), приведите:millis as u64. - Точность:
Durationможет содержать наносекунды, поэтому методas_millis()отбрасывает остаток. Если нужна дробная часть, используйтеas_secs_f64() * 1000.0. - Кроссплатформенность:
SystemTimeработает на Windows, Linux, macOS и других ОС.
Пример с дробными миллисекундами (f64)
use std::time::{SystemTime, UNIX_EPOCH};
fn get_unix_millis_f64() -> f64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs_f64() * 1000.0
}
fn main() {
println!("{:.3}", get_unix_millis_f64()); // например: 1698765432.123
}
Этот способ подходит для высокоточных замеров, где важна дробная часть миллисекунды.
<<Альтернатива: крейт chrono
Если вы работаете с датами и временем в более сложных сценариях (форматирование, часовые пояса, парсинг), рекомендую популярный крейт chrono. Он предоставляет более удобный API, чем стандартная библиотека.
Добавьте в Cargo.toml:
[dependencies]
chrono = "0.4"
Пример получения миллисекунд:
use chrono::Utc;
fn main() {
let millis = Utc::now().timestamp_millis();
println!("{}", millis); // i64
}
Метод timestamp_millis() возвращает i64 (а не u128), что удобно для совместимости с базами данных и API. Также chrono поддерживает:
- Форматирование даты (
format("%Y-%m-%d %H:%M:%S")) - Работу с часовыми поясами (
Local::now()) - Парсинг строк (
NaiveDateTime::parse_from_str)
Для простого замера времени выполнения кода лучше использовать std::time::Instant (он не зависит от системных часов и не может "скакнуть" при корректировке времени), но для получения абсолютного timestamp chrono — отличный выбор.
Ответов пока нет.
Войдите чтобы оставить ответ