windows下可用getsystemtimeasfiletime模拟gettimeofday:将filetime转ulonglong后减去116444736000000000ull,再分别除以10000000和取模除10得tv_sec与tv_usec。

Windows 下没有 gettimeofday,但可以用 GetSystemTimeAsFileTime 模拟
标准 C++(包括 POSIX)的 gettimeofday 在 Windows 默认不可用,MSVC 不提供该函数,直接调用会报 LNK2019: unresolved external symbol gettimeofday。这不是头文件没包含的问题,而是系统 API 层面缺失。
最轻量、最常用的做法是用 Windows 原生的 GetSystemTimeAsFileTime 手动转换:它返回自 1601-01-01 的 100 纳秒单位 FILETIME,减去 UNIX epoch(1970-01-01)偏移量即可得到秒+微秒结构体。
关键点:
-
FILETIME是 64 位整数,但低/高 32 位分开存储,必须先转成ULONGLONG再运算 - UNIX epoch 到 Windows epoch 的差值是
116444736000000000ULL(单位:100 纳秒) - 微秒 = 总 100 纳秒数 % 10000000 / 10;秒 = 总 100 纳秒数 / 10000000
一个可直接替换的 gettimeofday 兼容实现
以下代码定义在 .cpp 文件中即可使用,无需额外依赖,且行为与 Linux 版本一致(tv_sec 和 tv_usec):
#include <windows.h>
#include <sys><p>int gettimeofday(struct timeval<em> tp, void</em>) {
if (!tp) return -1;
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
ULONGLONG ll = (ULONGLONG)ft.dwLowDateTime + ((ULONGLONG)ft.dwHighDateTime tv_sec = (long)(ll / 10000000LL);
tp->tv_usec = (long)((ll % 10000000LL) / 10LL);
return 0;
}
</p></sys></windows.h>
注意:
- 不要放在头文件里重复定义,避免 ODR 违规
- 不支持时区或 DST,和原生
gettimeofday一样只返回 UTC 时间 - 精度实际约 15.6ms(取决于系统时钟分辨率),比 Linux 的
clock_gettime(CLOCK_MONOTONIC)差,但满足大多数日志/超时场景
用 clock_gettime 替代?Windows 10 1903+ 才有
Windows 10 build 18362(即 1903 版本)起,UCRT 提供了有限的 clock_gettime 支持,但仅限 CLOCK_REALTIME 和 CLOCK_MONOTONIC,且需要链接 mincore.lib。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
如果你的目标系统明确 ≥ Win10 1903,且项目已用 CMake 或支持条件编译,可以这样写:
#ifdef _WIN32
#if defined(WINVER) && WINVER >= 0x0A00 // 10.0
#include <time.h>
// 可用 clock_gettime(CLOCK_REALTIME, &ts)
#else
// fallback to GetSystemTimeAsFileTime
#endif
#endif
</time.h>
但多数企业环境仍需兼容 Win7/Win8.1,所以硬依赖 clock_gettime 并不现实。
第三方库方案:mingw-w64 或 libuv 自带封装
如果你已在用 MinGW-w64 工具链(如 MSYS2、Clang-CL),它的 CRT 已内置 gettimeofday 实现,直接调用即可,底层仍是 GetSystemTimeAsFileTime。
若项目已引入 libuv(如 Node.js C++ 插件),可用其跨平台接口:
#include <uv.h> uv_timeval64_t tv; uv_gettimeofday(&tv); // tv.tv_sec, tv.tv_usec </uv.h>
不过为一个函数引入整个 libuv 显得过重;真正值得考虑的是——如果你已经在用 boost::chrono 或 std::chrono::system_clock::now(),就别再碰 gettimeofday 了。C++11 后,std::chrono 是更现代、类型安全的选择,只是它不直接提供 struct timeval 格式,需手动转换。
最容易被忽略的一点:很多移植代码只处理了 tv_sec,却把 tv_usec 算错——除以 1000 或漏掉取模,导致时间戳跳变。务必验证微秒部分是否在 [0, 999999] 范围内。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










