Skip to content

介绍

Rust 标准库的 std::time 模块提供了处理时间的基础类型

类型作用
Duration时间间隔(一段时间, 比如 5 秒)
Instant时刻(用来测量耗时, 单调递增)
SystemTime系统时间(可以转换为日期, 但可能被调整)

注意点

std::time 只提供了"时间间隔"和"系统时钟", 没有提供日期/日历类型(比如"今天是 2026 年 6 月 1 日"), 日期相关的功能需要第三方库 chrono, 本章最后一节会介绍

时间间隔 Duration

Duration 表示一段时间的长度, 内部由"秒 + 纳秒"两部分组成

创建 Duration

方法作用
new由 (秒, 纳秒) 两部分创建
from_secs从秒创建
from_millis从毫秒创建
from_micros从微秒创建
from_nanos从纳秒创建
rust
use std::time::Duration;

fn main() {
    // 1. Duration::new: 由 (秒, 纳秒) 两部分创建
    let d = Duration::new(2, 500_000_000); // 2 秒 + 0.5 秒
    println!("{d:?}"); // 2.5s

    // 2. 从各种时间单位创建
    let secs = Duration::from_secs(90);
    println!("{secs:?}"); // 90s

    let millis = Duration::from_millis(1500);
    println!("{millis:?}"); // 1.5s

    let micros = Duration::from_micros(1_000_000);
    println!("{micros:?}"); // 1s

    let nanos = Duration::from_nanos(1_000);
    println!("{nanos:?}"); // 1µs
}

Duration 的运算

方法作用
checked_add加法, 溢出返回 None
saturating_sub减法, 不够减返回 0(不会变负)
mul乘法, 可以直接 duration * n
rust
use std::time::Duration;

fn main() {
    let a = Duration::from_secs(2);
    let b = Duration::from_secs(3);

    // checked_add: 加法, 返回 Option
    let c = a.checked_add(b).expect("溢出");
    println!("{c:?}"); // 5s

    // saturating_sub: 不够减时返回 0
    let small = Duration::from_secs(1);
    println!("{:?}", small.saturating_sub(b)); // 0ns
    println!("{:?}", b.saturating_sub(small)); // 2s

    // 乘法
    println!("{:?}", a * 3); // 6s

    // Duration 实现了比较运算
    println!("a < b = {}", a < b); // a < b = true
}

转换 Duration

方法作用
as_secs整秒部分(丢弃小数)
as_millis毫秒
as_micros微秒
as_secs_f64秒(浮点数, 带小数)
rust
use std::time::Duration;

fn main() {
    let d = Duration::from_millis(2500);

    // as_secs: 只取整秒部分, 丢弃小数
    println!("as_secs = {}", d.as_secs()); // as_secs = 2

    // as_millis / as_micros
    println!("as_millis = {}", d.as_millis()); // as_millis = 2500
    println!("as_micros = {}", d.as_micros()); // as_micros = 2500000

    // as_secs_f64: 带小数的秒
    println!("as_secs_f64 = {}", d.as_secs_f64()); // as_secs_f64 = 2.5
}

测量耗时 Instant

Instant 表示一个时刻, 常用于测量代码执行耗时, 它的时间是单调递增的, 不会因为系统时间被调整而受影响

测量代码执行耗时

rust
use std::time::Instant;

fn main() {
    // Instant::now: 记录当前时刻
    let start = Instant::now();

    // 模拟一段耗时操作(1 亿次循环)
    let mut sum = 0u64;
    for i in 0..100_000_000 {
        sum += i;
    }
    println!("sum = {sum}");

    // elapsed: 从 start 时刻到现在经过的时间
    let elapsed = start.elapsed();
    println!("耗时: {elapsed:?}"); // 耗时: 几十毫秒 (每次运行结果不同)
}

让线程休眠

rust
use std::thread;
use std::time::{Duration, Instant};

fn main() {
    // thread::sleep: 让当前线程休眠一段时间
    let start = Instant::now();
    thread::sleep(Duration::from_millis(100));
    println!("睡了 {:?}", start.elapsed()); // 睡了 100ms 左右 (每次运行略有差异)
}

利用这一点可以实现类似 JS 的定时器 API

rust
use std::{thread, time::Duration};

// 超时器
pub fn set_time_out<F>(callback: F, time_out: Duration)
where
    F: Fn(),
{
    thread::sleep(time_out); // 阻塞当前线程
    callback();
}

// 定时器
pub fn set_interval<F>(callback: F, time_out: Duration)
where
    F: Fn(),
{
    loop {
        thread::sleep(time_out); // 阻塞当前线程
        callback();
    }
}

系统时间 SystemTime

SystemTime 表示系统时间, 可以获取当前时间的UNIX 时间戳(距离 1970-01-01 的秒数)

获取当前时间戳

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

fn main() {
    // SystemTime::now: 当前系统时间
    let now = SystemTime::now();

    // duration_since(UNIX_EPOCH): 计算距离 1970-01-01 的时间
    // 返回 Result: 如果系统时间早于 1970 年会返回 Err
    let since_epoch = now.duration_since(UNIX_EPOCH).expect("系统时间异常");
    println!("距离 1970 年: {since_epoch:?}"); // 每次运行结果不同

    // 这就是常见的"UNIX 时间戳"
    println!("时间戳(秒): {}", since_epoch.as_secs()); // 每次运行结果不同
    println!("时间戳(毫秒): {}", since_epoch.as_millis());
}

比较两个时间点

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

fn main() {
    // elapsed: 当前时间距离该时刻经过的时间
    let t = SystemTime::now();
    println!("{:?}", t.elapsed().expect("系统时间异常")); // 极短的时间 (每次运行不同)

    // 模拟两个时间点: t2 比 t1 晚 5 秒
    let t1 = SystemTime::now();
    let t2 = t1 + Duration::from_secs(5);

    // duration_since: t2 距离 t1 过了多久
    let diff = t2.duration_since(t1).expect("时间倒退");
    println!("diff = {diff:?}"); // diff = 5s

    // 反过来计算会返回 Err(时间不能倒退)
    let result = t1.duration_since(t2);
    println!("{result:?}"); // Err(...)
    println!("{:?}", UNIX_EPOCH.elapsed().expect("系统时间异常")); // 系统启动至今的秒数
}

日期与日历(第三方库 chrono)

标准库没有日期类型, 处理"年/月/日/星期"需要第三方库, chrono 是事实标准

介绍与创建日期

方法作用
Local::now当前本地时间
Utc::now当前 UTC 时间
NaiveDate::from_ymd_opt手动创建日期(返回 Option)
rust
// Cargo.toml 添加依赖:
// [dependencies]
// chrono = "0.4"

use chrono::{Local, NaiveDate, Utc};

fn main() {
    // 1. 获取当前本地时间: 会受到服务器时区设置的影响
    let now = Local::now();
    println!("本地时间: {}", now.format("%Y-%m-%d %H:%M:%S")); // 每次运行结果不同

    // 2. 获取当前 UTC 时间(格林尼治时间)
    let utc = Utc::now();
    println!("UTC 时间: {}", utc.format("%Y-%m-%d %H:%M:%S")); // 每次运行结果不同

    // 3. 手动创建日期(返回 Option, 不合法返回 None)
    let date = NaiveDate::from_ymd_opt(2026, 6, 1).expect("日期不合法");
    println!("{date}"); // 2026-06-01

    // 不合法日期: 2 月没有 30 号
    let date = NaiveDate::from_ymd_opt(2026, 2, 30);
    println!("{date:?}"); // None
}

格式化与解析

常用格式符: %Y%m%d%H 时(24小时制) %M%S

rust
// Cargo.toml 添加依赖:
// [dependencies]
// chrono = "0.4"

use chrono::NaiveDate;

fn main() {
    let date = NaiveDate::from_ymd_opt(2026, 6, 1).expect("日期不合法");

    // format: 日期格式化为字符串
    println!("{}", date.format("%Y/%m/%d")); // 2026/06/01
    println!("{}", date.format("%Y年%m月%d日")); // 2026年06月01日

    // parse_from_str: 字符串解析为日期
    let parsed = NaiveDate::parse_from_str("2026-06-01", "%Y-%m-%d").expect("解析失败");
    println!("{parsed}"); // 2026-06-01

    // 格式不匹配会解析失败
    let result = NaiveDate::parse_from_str("2026-13-01", "%Y-%m-%d");
    println!("{result:?}"); // Err(ParseError(OutOfRange))
}

日期运算

rust
// Cargo.toml 添加依赖:
// [dependencies]
// chrono = "0.4"

use chrono::{Datelike, Days, NaiveDate};

fn main() {
    let d1 = NaiveDate::from_ymd_opt(2026, 1, 1).expect("日期不合法");

    // checked_add_days: 加天数(返回 Option, 溢出返回 None)
    let d2 = d1.checked_add_days(Days::new(100)).expect("日期溢出");
    println!("{d2}"); // 2026-04-11

    // 两个日期相减: 得到天数差
    let diff = d2 - d1;
    println!("相差 {} 天", diff.num_days()); // 相差 100 天

    // 星期几 (weekday 定义在 Datelike trait 上, 需要引入)
    println!("{d1} 是 {}", d1.weekday()); // 2026-01-01 是 Thu
}

时间戳与日期互转

rust
// Cargo.toml 添加依赖:
// [dependencies]
// chrono = "0.4"

use chrono::{DateTime, Utc};

fn main() {
    // 时间戳 -> 日期时间
    let dt = DateTime::from_timestamp(1_700_000_000, 0).expect("时间戳不合法");
    println!("{dt}"); // 2023-11-14 22:13:20 UTC

    // 日期时间 -> 时间戳
    let ts = dt.timestamp();
    println!("{ts}"); // 1700000000

    // 当前时间戳
    let now_ts = Utc::now().timestamp();
    println!("当前时间戳: {now_ts}"); // 每次运行结果不同
}

相关开源库

  • chrono: 日期时间处理的事实标准, Local会受到服务器时区设置的影响
  • chrono-tz: 处理时区相关的问题(比如: 将utc时间转为 Asia/Shanghai 时间)
  • time: chrono 的替代品, API 更严谨
  • humantime: 人类可读的时间格式解析与格式化(如 "2h 30m")
rust
// Cargo.toml 添加依赖:
// [dependencies]
// humantime = "2"

fn main() {
    // parse_duration: 解析人类可读的时间间隔
    let d = humantime::parse_duration("2h 30m").expect("解析失败");
    println!("{d:?}"); // 9000s

    // format_duration: 格式化为人类可读
    println!("{}", humantime::format_duration(d)); // 2h 30m
}

Released under the MIT License.