最可靠方法是std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(),返回long long类型毫秒时间戳(自1970-01-01 utc起),跨平台、无时区陷阱、精度安全。

用 std::chrono::system_clock 获取毫秒时间戳最可靠
直接用 std::chrono::system_clock::now() 配合 time_since_epoch() 转成毫秒,是 C++11 及以后最标准、跨平台、无依赖的做法。别用 gettimeofday() 或 clock_gettime() —— 前者在 Windows 上不可用,后者 Linux 专属且需额外链接。
常见错误是直接用 duration_cast<seconds>()</seconds> 再乘 1000,结果整数溢出或精度丢失;正确做法是统一 cast 到 milliseconds 后再调 count():
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<:chrono::milliseconds>(
now.time_since_epoch()).count();
</:chrono::milliseconds>
-
system_clock对应系统实时时钟(即你手机/电脑显示的时间),适合日志打点、HTTP 时间头等场景 - 返回值类型是
long long,能安全表示到公元 292471 年的毫秒数,不用担心 int 溢出 - Windows 和主流 Linux/macOS 下行为一致,不依赖编译器扩展
为什么不用 time(nullptr) + gettimeofday()?
有人想拼凑秒+微秒再换算成毫秒,但问题一堆:time(nullptr) 只有秒级精度;gettimeofday() 在 Windows 上根本不存在(MSVC 不提供);即使 Linux 下可用,它的 tv_usec 是微秒字段,除以 1000 取整会丢精度(比如 123456 微秒 → 123 毫秒,实际应为 123.456 → 向下取整成 123)。
更麻烦的是,gettimeofday() 已被 POSIX 标准标记为废弃,新项目应避免使用。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 混合使用
time_t和struct timeval容易类型混乱,尤其在 32 位系统上time_t可能是 32 位整型,2038 年就溢出 - 不同平台对
gettimeofday()的实现细节有差异(如是否受 NTP 调整影响),而system_clock行为由标准明确定义
如果需要高精度(微秒/纳秒),仍用 chrono,但注意时钟类型
system_clock 满足绝大多数“带日期的时间戳”需求,但若做性能分析(比如函数耗时测量),该换 steady_clock —— 它不随系统时间跳变而回拨,保证单调递增。
要微秒级时间戳(非仅测量差值),仍得靠 system_clock,只是把 milliseconds 换成 microseconds:
auto us = std::chrono::duration_cast<:chrono::microseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
</:chrono::microseconds>
-
steady_clock的 epoch 是未定义的(通常为进程启动或机器开机),不能直接转成“自 1970-01-01 起的微秒数” - 某些嵌入式平台或旧编译器(如 GCC 4.8)中
system_clock::time_since_epoch()的精度可能只到秒,此时需确认system_clock::period::num / system_clock::period::den是否为 1/1000000000(纳秒)
Windows 下 GetSystemTimeAsFileTime() 是备选,但不推荐
它返回的是 Windows FILETIME(100 纳秒为单位,从 1601 年起),转成毫秒需先减去 1601→1970 的偏移(116444736000000000LL),再除以 10000:
FILETIME ft; GetSystemTimeAsFileTime(&ft); ULARGE_INTEGER ul; ul.LowPart = ft.dwLowDateTime; ul.HighPart = ft.dwHighDateTime; long long ms = (ul.QuadPart - 116444736000000000LL) / 10000;
- 代码冗长、易错(特别是大小端和 32 位截断风险)
- 完全 Windows 锁定,无法跨平台编译
- 相比
chrono版本,没有可读性优势,也没有性能优势(现代system_clock::now()在 Windows 上底层就是调的类似 API)
除非你在写纯 Win32 DLL 且不能用 STL,否则没必要绕开 chrono。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










