c++中如何获取系统当前的毫秒级时间戳_c++高精度时间获取【详解】

应根据用途选择:测时间间隔用 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(
    now.time_since_epoch()).count(); // 返回自 epoch 起的毫秒数
// ms 是 long long 类型,例如 1717023456789

Windows 下 GetSystemTimeAsFileTime 为什么不该优先用?

虽然 Win32 API 提供了高精度、无 STL 依赖的 GetSystemTimeAsFileTime,但它返回的是 100 纳秒为单位的 FILETIME,需要手动减去 Windows epoch(1601-01-01)再换算成 Unix 毫秒,容易出错:

  • 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)上都稳定映射到最合适的底层时钟源。