最可靠方式是用同一 clock(如 steady_clock)获取时间点后相减得 duration,再用 duration_cast 转毫秒;混用 clock 类型编译报错,steady_clock 适合测间隔,system_clock 可转真实时间但受系统时间调整影响。

用 std::chrono 计算毫秒级时间差最可靠
直接用 std::chrono::steady_clock 或 std::chrono::system_clock 获取时间点,再用减法得到 duration,这是 C++11 以后唯一推荐的方式。老式 time() + difftime() 只能到秒级,且不处理时区和夏令时跳跃。
常见错误是混用不同 clock 类型(比如用 system_clock::now() 减 steady_clock::now()),编译器会报错:「no match for ‘operator-’」。必须保证两个时间点来自同一个 clock。
-
steady_clock适合测间隔(不受系统时间调整影响),但返回值不能直接转成「年月日」 -
system_clock对应真实时间,可转time_t,但若用户手动调系统时间,差值会跳变 - 想输出毫秒:用
std::chrono::duration_cast<:chrono::milliseconds>(end - start).count()</:chrono::milliseconds> - 避免隐式转换:不要写
(end - start).count()默认类型,它依赖 clock 的精度(可能是纳秒或微秒)
计算带日期的时间差要用 std::chrono::time_point + 手动拆解
std::chrono 本身不提供「多少天、几小时、几分钟」这种结构化差值。它只给一个总时长(如 987654321ms),你要自己除以 24h/3600s/60s 等来拆。
注意:system_clock::time_point 的 epoch 是 1970-01-01 00:00:00 UTC,但 daylight saving time(夏令时)切换当天,两个 time_point 相减仍正确——因为 system_clock 底层基于 Unix 时间戳(已修正 DST 跳变)。
- 别用
localtime()或gmtime()对两个时间分别解析再相减,这会忽略闰秒和 DST 边界问题 - 如果真要按日历算「2023-03-10 到 2023-03-15 是 5 天」,得用第三方库如
date.h(Howard Hinnant’s date library) - 简单场景下,用
std::chrono::duration_cast<:chrono::days>(diff)</:chrono::days>可得整数天数,但它是按 24 小时算的,不是日历天
跨平台获取高精度时间差,Windows 上别用 GetTickCount()
GetTickCount() 最大值约 49.7 天就会回绕,且精度只有 ~10–15ms;QueryPerformanceCounter() 虽然精度高,但需配对 QueryPerformanceFrequency() 换算,还可能因 CPU 频率调节不准。C++ 标准库的 steady_clock 在 Windows 上底层就调用 QueryPerformanceCounter,但封装好了换算逻辑,直接用更安全。
- Linux/macOS 上
steady_clock基于clock_gettime(CLOCK_MONOTONIC, ...),稳定可靠 - 若必须用 WinAPI,至少用
GetTickCount64()避免回绕,但它仍是毫秒级,不如steady_clock精确 - 测试性能时,确保两次
now()调用之间没发生线程调度或中断延迟(尤其在 debug 模式下)
容易被忽略的陷阱:auto 推导导致精度丢失
写 auto start = std::chrono::steady_clock::now(); 没问题,但若中间做了 auto diff = end - start;,再传给函数或存入变量,可能因模板推导丢失精度——比如某些编译器把 duration 推成 std::chrono::nanoseconds,而你后续用 .count() 当 int 处理,溢出风险很高。
- 显式指定类型更稳妥:
auto diff = std::chrono::duration_cast<:chrono::milliseconds>(end - start);</:chrono::milliseconds> - 别把
duration存进int或long:用diff.count()前先确认值范围,毫秒级差值超过 24 天就会超 int32 - 日志打印时,直接用
std::cout 容易误读单位,建议打全:<code>std::cout (diff).count()
真正麻烦的不是算差值,而是搞清你要的是「物理流逝时间」还是「日历时间跨度」——前者用 steady_clock,后者得引入日期库,标准库不负责这个。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











