最常用方式是用std::chrono::duration_cast(system_clock::now().time_since_epoch()).count()获取unix时间戳(秒级),结果为long long类型;毫秒级同理用milliseconds;转本地时间需经to_time_t再调用localtime_s/r;std::time(nullptr)仅适用于纯秒级且无chrono运算场景。

用 std::chrono::system_clock 获取 Unix 时间戳(秒级)
最常用也最直接的方式是通过 std::chrono::system_clock 转换为自纪元以来的秒数。它对应系统本地时区的 UTC 时间,不是本地时间,这点容易误解。
关键点:
-
system_clock::now()返回的是一个time_point,需用time_since_epoch()拆解 - 必须显式转换为
seconds,否则可能截断或溢出(比如用count()直接取纳秒值会很大) - 结果是
long long类型的秒数,即标准 Unix 时间戳
auto now = std::chrono::system_clock::now();
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(
now.time_since_epoch()).count();
// seconds 就是标准时间戳,例如 1717023456
获取毫秒级或微秒级时间戳(带精度)
很多场景需要更高精度,比如日志打点、性能测量。这时不能只用 seconds,得用 milliseconds 或 microseconds,但要注意:高精度时间戳 ≠ 更准的时钟,只是分辨率更高。
常见错误:
立即学习“C++免费学习笔记(深入)”;
- 用
duration_cast<milliseconds>(...).count()</milliseconds>得到的是毫秒数,但它是从纪元开始算的,不是“当前秒内的毫秒” - 误以为
system_clock在所有平台都支持毫秒级稳定更新——Windows 上实际精度常为 15ms 左右,Linux 通常更好 - 跨平台代码中,避免依赖
system_clock::is_steady为 true(它不保证稳态,仅表示是否受系统时间调整影响)
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count(); // 例如 1717023456123
转成可读的本地时间字符串(非 UTC)
system_clock::to_time_t 可以把时间点转成 C 风格的 time_t,再用 localtime_r(Linux/macOS)或 localtime_s(Windows)转成本地时区结构体。注意:不要用 localtime(线程不安全)。
关键细节:
-
system_clock的时间点本质是 UTC,to_time_t不做时区转换,只是格式映射 - 不同平台对夏令时、时区数据库的支持有差异;若需严格时区处理(如 “Asia/Shanghai”),应改用
date.h库或 C++20 的<chrono></chrono>时区扩展 - Windows 下必须用
localtime_s并传入缓冲区地址,否则编译失败或触发安全警告
auto now = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(now);
#ifdef _WIN32
struct tm tm_buf{};
localtime_s(&tm_buf, &t);
#else
struct tm tm_buf{};
localtime_r(&t, &tm_buf);
#endif
为什么不用 std::time(nullptr)?
虽然 std::time(nullptr) 最快、最轻量,但它返回的是 time_t,类型和精度由平台定义(C++ 标准只要求能表示年月日时分秒),且无法直接参与 chrono 的运算或等待逻辑(比如 std::this_thread::sleep_until 必须用 time_point)。
适用边界很明确:
- 只需要秒级时间戳、且不涉及后续时间计算或等待 → 用
std::time更简洁 - 要和
std::chrono::steady_clock对齐、做差值、休眠、或未来升级到高精度 → 必须用system_clock::now() - 混用
time_t和chrono::time_point时,务必经过system_clock::from_time_t转换,否则行为未定义
真正麻烦的不是怎么取时间,而是搞清你要的是“纪元偏移量”“本地可读时间”还是“用于等待的稳态时钟”,三者底层目的完全不同。











