最可靠方式是用std::chrono::system_clock::now()获取时间点,duration_cast截断到毫秒并count()得整型毫秒数;取本秒内毫秒部分可用ms_total % 1000(ms_total≥0安全)。

用 std::chrono::system_clock 获取毫秒级时间戳(含小数部分)
标准库里最可靠的方式是用 std::chrono::system_clock,它返回的是自纪元起的纳秒级精度时间点,再手动截取毫秒部分——注意:不是四舍五入,而是直接丢弃微秒及更小单位。
常见错误是误用 time(nullptr) 或 gettimeofday(),它们只能到秒或微秒,且跨平台性差;而 system_clock::now() 是 C++11 起标准化的方案,Windows/macOS/Linux 都支持。
- 先调用
std::chrono::system_clock::now()得到time_point - 用
time_point.time_since_epoch()转为duration - 用
duration_cast<:chrono::milliseconds>()</:chrono::milliseconds>截断到毫秒(向下取整) - 再用
.count()拿到整型毫秒数
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<:chrono::milliseconds>(
now.time_since_epoch()).count();
// ms 就是自 1970-01-01 00:00:00 UTC 起的毫秒数
</:chrono::milliseconds>
只取“当前秒内的毫秒部分”(0–999)
有些日志或协议只要求显示“本秒内过了多少毫秒”,比如 123 而不是完整时间戳。这时候不能直接对完整毫秒数取模——因为 ms % 1000 在负时间(极少见)或某些时钟偏移下可能出错,稳妥做法是先转成 time_t 再算。
- 用
system_clock::to_time_t(now)得到秒级时间 - 把该
time_t转回time_point,再减去now - 或者更直白:用
duration_cast<ms>(now.time_since_epoch())</ms>后取% 1000,只要确保now是正向时间(实际总是如此)
auto ms_total = std::chrono::duration_cast<:chrono::milliseconds>(
now.time_since_epoch()).count();
int ms_in_second = static_cast<int>(ms_total % 1000); // 安全,ms_total ≥ 0
</int></:chrono::milliseconds>
Windows 下 GetSystemTimeAsFileTime 的陷阱
有人会查到 Windows API 的 GetSystemTimeAsFileTime,它返回的是 FILETIME(100 纳秒为单位),换算后看似能得毫秒。但要注意两点:
- FILETIME 基准是 1601 年 1 月 1 日,不是 Unix 纪元,差 11644473600 秒,容易漏减导致结果错 300 多年
- 它不保证单调性,系统时间被手动调整时可能跳变;而
system_clock在多数实现中基于高性能计数器,更稳
除非你在写内核驱动或必须兼容 XP,否则别碰这个 API。
毫秒部分不是“随机数”,它依赖系统时钟精度和调度延迟
即使代码写对了,连续两次调用得到的毫秒差也未必是 1——尤其在高负载或虚拟机里,system_clock::now() 的实际分辨率可能是 15ms(Windows 默认)、10ms(某些 Linux 内核)甚至更高。这不是 bug,是 OS 层限制。
如果你真需要亚毫秒级稳定间隔,得用 std::chrono::high_resolution_clock,但它不保证是 wall-clock 时间(可能随 CPU 频率缩放),不能用于生成时间戳。
真正容易被忽略的点:毫秒截断本身不耗时,但 system_clock::now() 是系统调用,频繁调用会影响性能;如果只是打日志,建议缓存一次结果复用,而不是每行都算。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











