外观
第 3 节:chrono——日期时间
一句话:标准库只有"时刻"(内置 API 篇第 7 节),没有"日历"。chrono 补上:格式化、解析、日期运算、时区——真实项目的日期时间全家桶。
安装
bash
cargo add chrono高频四件套 ⭐
1. 现在几点了
rust
use chrono::Local;
let now = Local::now(); // 本地时间
println!("{}", now.format("%Y-%m-%d %H:%M:%S"));
// 2026-08-01 14:44:34%Y 年、%m 月、%d 日、%H 时、%M 分、%S 秒——格式化占位符和很多语言一样。
2. 字符串 ↔ 日期
rust
use chrono::NaiveDate;
// 解析(格式必须严格匹配)
let birthday = NaiveDate::parse_from_str("2026-08-01", "%Y-%m-%d").expect("解析失败");
// 格式化
println!("{}", birthday.format("%Y/%m/%d")); // 2026/08/01解析失败返回 Result(用户输入的日期格式五花八门,别 unwrap)。
3. 日期运算
rust
use chrono::Duration;
let next_week = birthday + Duration::days(7); // 加 7 天
let duration = end - start; // 两个时刻相减
println!("{} 分钟", duration.num_minutes()); // 间隔换算:num_days/num_hours/num_minutes4. 时区转换
rust
use chrono::{DateTime, TimeZone, Utc, Local};
let utc_time: DateTime<Utc> = Utc.with_ymd_and_hms(2026, 8, 1, 10, 30, 0).unwrap();
let local_time = utc_time.with_timezone(&Local); // UTC → 本地服务器存 UTC,展示转本地——真实项目的铁律。
高频进阶:时间戳与 JSON 集成 ✨
UNIX 时间戳(秒)和 chrono 互转:
rust
use chrono::{TimeZone, Utc};
let timestamp = Utc::now().timestamp(); // i64 秒
let back = Utc.timestamp_opt(timestamp, 0).unwrap();和 serde 配合(第 1 节):chrono 有 serde feature,DateTime<Utc> 直接序列化成时间戳/RFC3339:
rust
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Event {
created_at: DateTime<Utc>, // 自动变成 ISO 8601 字符串
}常见误用与坑
NaiveDatevsDateTime:NaiveDate是"没有时区的日期"(生日、日历);DateTime<Utc>/DateTime<Local>是"带时区的时刻"。存数据库/跨时区,用DateTime<Utc>;只关心"哪一天",用NaiveDate- 解析格式要"门当户对":
"2026-8-1"用%Y-%m-%d解析会失败(月份没补零)——要宽容,试试%Y-%-m-%-d + Duration::days(30)跨月安全吗:安全!chrono 的日期运算是日历级的(1 月 31 日 + 1 个月 = 2 月 28/29 日)- 时区别乱拼:
Local::now().timestamp()得到的是 UTC 时间戳(正确);但"本地 8 点"字符串直接 parse 成 UTC 会差 8 小时——需要时区时用DateTime显式带时区 - 版本 0.4 的 API 名称:
Utc::now()/Local::now()是新写法;老教程的Utc::now().naive_local()等旧 API 已弃用