Windows下获取UTC毫秒最直接的方式是调用GetSystemTimeAsFileTime,它返回自1601-01-01 UTC起的100纳秒计数,除以10000即得毫秒值,天然UTC、无时区影响、轻量可靠。

Windows 下用 GetSystemTimeAsFileTime 获取 UTC 毫秒最直接
Windows API 提供的 GetSystemTimeAsFileTime 返回的是自 1601-01-01 UTC 起的 100 纳秒(即 0.1 微秒)计数,换算成毫秒只需除以 10000。它不依赖本地时区,天然就是 UTC,且无系统调用开销,比 GetSystemTime 或 C++20 std::chrono::utc_clock 更轻量、更可靠。
常见错误是直接用 SYSTEMTIME 结构体配合 GetSystemTime,结果受本地时区影响;或者误把 FILETIME 的低/高 32 位当普通整数拼接,忽略符号扩展问题。
-
FILETIME是 uint64_t 的别名,但 Windows SDK 中定义为两个DWORD(dwLowDateTime和dwHighDateTime),必须用ULARGE_INTEGER或位运算安全合并 - 推荐用
ULARGE_INTEGER:先赋值再取QuadPart,避免手动移位出错 - 除以 10000 后截断即可得毫秒(
uint64_t足够覆盖到公元 3000 年)
uint64_t get_utc_ms() {
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
ULARGE_INTEGER ul;
ul.LowPart = ft.dwLowDateTime;
ul.HighPart = ft.dwHighDateTime;
return ul.QuadPart / 10000;
}
C++20 std::chrono::utc_clock 在 Windows 上可用但需注意编译器支持
MSVC 19.30+(VS2022 17.0+)开始支持 std::chrono::utc_clock,但 Clang/LLVM on Windows 默认不启用,GCC for Windows(MinGW)基本不支持。即使可用,其底层仍可能调用 GetSystemTimeAsFileTime,但多了类型转换和时区库依赖。
容易踩的坑是直接用 system_clock::now() 误以为是 UTC —— 它在 Windows 上返回的是本地时间对应的 epoch 时间戳(基于 1970-01-01 UTC,但值已按本地偏移调整),不是纯 UTC。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 若用
utc_clock,必须搭配std::chrono::time_point<std::chrono::utc_clock>,不能混用system_clock - 转换为毫秒需经
time_since_epoch().count(),单位是纳秒,再除以 1000000 - 链接时需确保启用了
/std:c++20和/Zc:__cplusplus(MSVC)
跨平台兼容时别硬套 Windows API,但 Windows 独立项目优先选 GetSystemTimeAsFileTime
如果代码只跑 Windows,GetSystemTimeAsFileTime 是事实标准:无额外依赖、无异常、无分配、精度稳定在 15.6ms(系统 tick)以内。POSIX 的 clock_gettime(CLOCK_REALTIME) 在 Windows 不可用,而 std::chrono::steady_clock 不是 UTC,std::chrono::system_clock 又非真正 UTC。
有人试图用 gmtime + time 组合,但 time() 返回的是本地 time_t,再传给 gmtime 会因夏令时规则或时区数据库缺失导致偏差,尤其在嵌入式或精简系统上不可靠。
- MinGW-w64 提供了部分 POSIX 接口,但
clock_gettime对CLOCK_REALTIME的实现仍是封装GetSystemTimeAsFileTime - 若已有跨平台抽象层(如 Boost.Chrono),确认其 Windows backend 是否绕过了
GetSystemTimeAsFileTime—— 有些旧版本会 fallback 到低精度GetTickCount64
毫秒值用于日志或序列号时,注意单调性和重复风险
GetSystemTimeAsFileTime 返回的是 wall-clock 时间,受系统时间调整(NTP 同步、手动修改)影响,可能回退或跳变。单纯用毫秒值做唯一 ID 或排序依据,在高频写入场景下(如每毫秒多次调用)可能重复。
这不是 API 错,而是设计约束:Windows 系统 tick 通常为 15–16ms,GetSystemTimeAsFileTime 虽然分辨率高,但实际更新频率受限于系统计时器。
- 若需单调递增,建议组合毫秒 + 自增计数器(每毫秒内累加)
- 若用于日志时间戳,可接受重复,但别拿它做分布式 ID 的核心熵源
- 调试时发现时间“倒流”,先查是否启用了 Windows Time Service 的强制同步
GetSystemTimeAsFileTime 就是那个最贴近金属的选项 —— 其他方案要么多一层间接,要么少一层保障。

















