Rust 用 chrono 处理日期时间:时区转换、工期计算与格式化避坑

test12026-10-173 次阅读

为什么自己拼时间字符串容易错

时区、夏令时、格式化符号都是坑。用 chrono 可以把时间当成带类型的对象来算,而不是一堆字符串。下面以项目排期场景演示常见操作。

当前时间与时区转换

use chrono::{DateTime, Utc, FixedOffset, TimeZone};

fn main() {
    let now_utc: DateTime<Utc> = Utc::now();
    let cst = FixedOffset::east_opt(8 * 3600).unwrap(); // UTC+8
    let local = now_utc.with_timezone(&cst);
    println!("UTC: {} 本地: {}", now_utc, local);
}

Utc::now 拿到的是带 UTC 类型的时刻,with_timezone 只是换显示,底层那一瞬间不变,避免手动加减偏移出错。

工期计算与比较

use chrono::{Duration, NaiveDate, Weekday};

fn work_days(start: NaiveDate, end: NaiveDate) -> i64 {
    let mut days = 0;
    let mut cur = start;
    while cur < end {
        let wd = cur.weekday();
        if wd != Weekday::Sat && wd != Weekday::Sun {
            days += 1;
        }
        cur = cur + Duration::days(1);
    }
    days
}

fn main() {
    let start = NaiveDate::from_ymd_opt(2026, 10, 1).unwrap();
    let end = NaiveDate::from_ymd_opt(2026, 10, 17).unwrap();
    println!("工作日数: {}", work_days(start, end));
}

格式化与解析

use chrono::{NaiveDate, NaiveDateTime};

fn main() {
    let dt = NaiveDate::from_ymd_opt(2026, 10, 17)
        .unwrap()
        .and_hms_opt(9, 30, 0)
        .unwrap();
    // %Y 四位年,%m 带零月份,%d 带零日期
    let s = dt.format("%Y-%m-%d %H:%M:%S").to_string();
    println!("{}", s);

    let parsed = NaiveDateTime::parse_from_str("2026-10-17 09:30:00", "%Y-%m-%d %H:%M:%S");
    println!("{:?}", parsed);
}

容易踩的点

  • NaiveDateTime 不带时区,跨时区传输前先转 DateTime<Utc> 再序列化为时间戳。
  • 解析失败返回 Result,别用 unwrap 直接吞掉错误,生产环境应向上返回。
  • 工期计算别用简单相减,周末和节假日需要逐日判断。
  • 格式化符号区分大小写,写错会得到意料之外的输出。
T

test1

文章作者

为什么自己拼时间字符串容易错 时区、夏令时、格式化符号都是坑。用 chrono 可以把时间当成带类型的对象来算,而不是...

分类
技术
发布时间
2026-10-17
字数
约 1553 字
阅读
3 次