GetSystemTimeAsFileTime 是 Windows C++ 中最轻量的系统时间获取方式,直接返回 64 位 FILETIME,无时区转换与额外系统调用,开销极小,适用于性能计时和日志打点。

GetSystemTimeAsFileTime 是最轻量的系统时间获取方式
在 Windows C++ 中,如果只需要高精度、低开销的系统时间戳(比如做性能计时或日志打点),GetSystemTimeAsFileTime 是首选。它直接返回 64 位 FILETIME,不涉及本地时区转换,也不调用 NLS 或注册表查询,调用开销极小(通常
常见错误是把它和 GetLocalTime 混用:前者返回 UTC 时间的 100 纳秒精度整数,后者返回带时区偏移的 SYSTEMTIME 结构,性能差一个数量级且可能触发时区数据加载。
-
FILETIME的值是从 1601-01-01 00:00:00 UTC 开始的 100 纳秒计数,不是 Unix 时间戳 - 如需转为秒级时间戳,推荐用
ULARGE_INTEGER拆包再除以 10⁷(即 10000000),不要用FileTimeToSystemTime多绕一圈 - 该函数线程安全,无需同步,在高频循环中可放心调用
需要本地时间显示?用 GetLocalTime 而非 GetSystemTime
当输出日志、UI 显示或写入用户可见文本时,必须用 GetLocalTime 获取带本地时区和夏令时修正的时间。虽然它比 GetSystemTimeAsFileTime 慢,但这是正确性要求,不是性能优化点。
容易踩的坑是误以为 GetSystemTime + 手动加时区偏移就能替代 GetLocalTime——Windows 时区规则复杂,夏令时切换日期每年不同,手动计算必然出错。
立即学习“C++免费学习笔记(深入)”;
-
GetLocalTime返回的SYSTEMTIME中wYear~wMilliseconds都已按当前时区和 DST 规则换算完毕 - 若后续要格式化为字符串,优先用
GetDateFormatEx或GetTimeFormatEx,它们支持 Unicode 和区域设置,比wsprintf安全可靠 - 注意:
GetLocalTime在系统时区变更后不会自动刷新缓存,但每次调用都实时读取,无需额外处理
跨平台代码里慎用 time() / localtime_s —— Windows 下有兼容陷阱
如果项目同时跑 Linux 和 Windows,直接用标准库 time() + localtime_s() 看似方便,但在 Windows 上容易触发两个隐蔽问题:一是 localtime_s 默认依赖全局时区状态,多线程下可能被其他线程修改;二是它内部会调用 _tzset,首次调用较慢且可能读取注册表。
更麻烦的是,Visual Studio 不同版本对 localtime_s 的实现细节不同:2015 及之前版本在时区变更后不自动更新,2017+ 改进但仍不如 GetLocalTime 稳定。
- 跨平台项目建议封装一层:Windows 走
GetLocalTime,Linux 走clock_gettime(CLOCK_REALTIME, ...) - 绝对避免在性能敏感路径(如渲染循环、网络包处理)中调用
localtime_s - 若必须用标准库,至少确保
_tzset在程序启动时调用一次,并在时区变更消息(WM_TIMECHANGE)中再次调用
FILETIME 转 std::chrono::time_point 的安全写法
C++11 后很多代码倾向用 std::chrono,但直接把 FILETIME 当作纳秒传给 duration_cast 会溢出或精度丢失——因为 FILETIME 是 100 纳秒单位,而 std::chrono::system_clock::time_since_epoch() 基准是 1970 年,两者起点不同。
正确做法是先换算为 Unix 时间戳(单位:100ns),再构造 time_point。别信网上抄来的“+116444736000000000LL”硬编码常量,它在某些编译器上因字面量类型推导失败导致截断。
- 用
ULARGE_INTEGER接收FILETIME,然后减去从 1601 到 1970 的 100ns 总数:116444736000000000ULL - 再除以 10 得到微秒,或除以 10000 得到毫秒,再用
std::chrono::microseconds构造time_point - 不要用
std::chrono::file_clock(C++20 新增),它在 MSVC 2022 22.38 前不完全支持 Windows,行为不可靠
FILETIME 的 100 纳秒粒度和 1601 年起点是 Windows 内部约定,改不了也绕不开;所有转换逻辑一旦写错,时间就偏移数百年——这点比时区还致命,但调试时往往只看到“时间不对”,没人怀疑起点错了。


















