应根据用途选择:测时间间隔用 steady_clock,记录日历时间(如 unix 时间戳)用 system_clock;转换时须用 duration_cast 显式转毫秒并调用 count(),避免截断或溢出。

用 std::chrono::steady_clock 还是 std::chrono::system_clock?
获取“当前时间戳”这个需求,本质要分清两个目标:测时间间隔 用 steady_clock,对应日历时间(如日志打点) 用 system_clock。毫秒级精度两者都支持,但行为完全不同:steady_clock 不受系统时间调整影响,适合计时;system_clock 可转成 time_t 和本地时间,适合记录真实时刻。
如果你要的是“类似 Unix 时间戳(秒+毫秒)”,必须用 system_clock;如果只是想测函数执行耗时,steady_clock 更可靠。
system_clock::now() 转毫秒时间戳的正确写法
直接调用 time_since_epoch() 得到的是纳秒/微秒级 duration,不能直接强转。必须用 duration_cast 显式转换,否则在不同编译器或优化级别下可能截断或溢出。
-
system_clock::time_point的 epoch 是 UTC 1970-01-01 00:00:00(即 Unix epoch) - 转毫秒需先 cast 到
milliseconds,再用.count() - 注意:
system_clock::rep通常是long long,但不保证——别用int接返回值
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count(); // 返回自 epoch 起的毫秒数
// ms 是 long long 类型,例如 1717023456789
Windows 下 GetSystemTimeAsFileTime 为什么不该优先用?
虽然 Win32 API 提供了高精度、无 STL 依赖的 GetSystemTimeAsFileTime,但它返回的是 100 纳秒为单位的 FILETIME,需要手动减去 Windows epoch(1601-01-01)再换算成 Unix 毫秒,容易出错:
立即学习“C++免费学习笔记(深入)”;
- FILETIME 到 Unix 时间戳需减去 116444736000000000LL(100ns 单位的差值)
- 再除以 10000 得到毫秒 —— 两步整数运算极易因溢出或截断丢失精度
- 跨平台代码中混用 Win32 API 会破坏可移植性
除非你已在裸金属/驱动层开发,且明确禁止 STL,否则没必要绕开 std::chrono。
Linux/macOS 上 clock_gettime(CLOCK_REALTIME, ...) 的兼容性陷阱
POSIX 的 clock_gettime 确实能拿到纳秒级时间,但要注意:CLOCK_REALTIME 会随 adjtimex 或 NTP 调整跳变,和 system_clock 行为一致;而 CLOCK_MONOTONIC 类似 steady_clock,不跳变但无法映射到日历时间。
若你用它替代 system_clock,必须自己处理 epoch 换算(timespec.tv_sec 是秒,tv_nsec 是纳秒),而且 C++11 后标准库已封装好这些细节——重复造轮子没收益。
真正容易被忽略的是:某些旧版 glibc(CLOCK_MONOTONIC_RAW,但 std::chrono::steady_clock 在各主流编译器(GCC/Clang/MSVC)上都稳定映射到最合适的底层时钟源。











