GetSystemTime 获取 UTC 时间,适合日志和时间戳;GetLocalTime 返回本地时区时间,受系统设置影响;高精度用 GetSystemTimeAsFileTime + FILETIME;C++11+ 推荐 std::chrono::system_clock::now(),但需注意时区语义一致性。

GetSystemTime 函数直接获取 UTC 时间
Windows 提供的 GetSystemTime 是最轻量、最常用的方式,它把当前系统 UTC 时间写入 SYSTEMTIME 结构体,不涉及时区转换或权限问题,适合绝大多数日志记录、时间戳生成场景。
注意:返回的是协调世界时(UTC),不是本地时间。如果误用为本地时间,会导致 8 小时偏差(东八区)。
-
SYSTEMTIME是一个包含年、月、日、时、分、秒、毫秒字段的结构体,所有字段都是WORD(16 位无符号整数) - 调用前必须初始化结构体(如
SYSTEMTIME st = {0};),否则未赋值字段可能为随机值 - 不需要链接额外库,
#include <windows.h>后即可使用
SYSTEMTIME st = {0};
GetSystemTime(&st);
// st.wYear, st.wMonth, st.wDay 等字段现在已填充
GetLocalTime 获取本地时区时间
如果明确需要带本地时区偏移的时间(比如显示给用户看),应改用 GetLocalTime。它和 GetSystemTime 接口完全一致,但底层会读取系统时区设置并做换算。
风险点在于:时区信息由系统维护,若用户手动修改了时区或启用了自动夏令时,GetLocalTime 返回结果会随之变化,而 GetSystemTime 始终稳定。
立即学习“C++免费学习笔记(深入)”;
- 两者性能无差异,都是内核态快速拷贝,无需担心开销
- 在服务进程(如 Windows Service)中,
GetLocalTime可能受会话隔离影响——某些情况下返回的是服务会话的时区,而非登录用户的时区 - 跨机器部署时,依赖本地时区配置,不利于时间一致性校验
FILETIME + GetSystemTimeAsFileTime 更适合高精度或时间差计算
当需要微秒级精度、或频繁做时间差运算(如性能计时)时,GetSystemTimeAsFileTime 配合 FILETIME 是更优选择。它返回的是自 1601-01-01 起的 100 纳秒单位计数,无格式化开销,也避免了 SYSTEMTIME 的拆分/重组成本。
-
FILETIME是两个DWORD组成的 64 位值,低位在前(dwLowDateTime/dwHighDateTime),直接比较大小即可判断先后 - 若需转为可读时间,必须调用
FileTimeToSystemTime,但该转换有约 15 微秒开销,高频调用要避开 - 不能直接 printf 输出,常见错误是把
FILETIME当作指针传给%lld—— 正确做法是先组合为LARGE_INTEGER
FILETIME ft; GetSystemTimeAsFileTime(&ft); LARGE_INTEGER li; li.LowPart = ft.dwLowDateTime; li.HighPart = ft.dwHighDateTime; // li.QuadPart 即 100ns 单位总值
std::chrono::system_clock::now() 在 C++11+ 中的替代方案
纯标准 C++ 场景下(如跨平台代码),推荐用 std::chrono::system_clock::now()。它在 Windows 上底层仍调用 GetSystemTimeAsFileTime,但封装了类型安全与单位抽象。
关键限制:C++ 标准只要求 system_clock 表示“系统实时钟”,并未规定是否为 UTC —— 实际上 MSVC 和 Clang-cl 都保证它是 UTC,但 GCC on MinGW 可能因实现差异略有不同,生产环境建议加运行时校验。
- 返回类型是
time_point,转SYSTEMTIME需经std::chrono::system_clock::to_time_t→gmtime_s两步,比原生 API 多 2~3 次函数调用 - 若只需纳秒级差值,直接用
duration_cast<nanoseconds>(now - last),零开销 - 不要用
std::put_time直接格式化,Windows 默认 locale 下可能崩溃;优先用sprintf_s或std::format(C++20)
真正容易被忽略的是时区语义混淆:很多 bug 不是 API 调用错,而是把 GetSystemTime 当作本地时间用,或者在分布式日志里混用 GetLocalTime 和 GetSystemTime。UTC 是唯一可靠锚点,本地时间只应在展示层出现。


















