最可靠的方式是用 std::chrono::system_clock::now() 配合 duration_cast 转秒级时间戳,类型安全、跨平台、无符号、默认 Unix 时间戳;避免 time() 和 gettimeofday() 等 C 接口,因其存在精度低、线程不安全、32 位溢出等隐患。

直接用 std::chrono::system_clock::now() 转成秒级时间戳最可靠,别碰 time() 或 gettimeofday() 这类 C 风格接口——它们在跨平台、精度、线程安全上都有隐性坑。
用 std::chrono 获取秒级时间戳(推荐)
这是 C++11 之后的标准做法,类型安全、无符号、跨平台,且默认就是 Unix 时间戳(自 1970-01-01 00:00:00 UTC 起的秒数)。
-
std::chrono::system_clock::now()返回的是一个高精度时间点(可能含纳秒),需显式截断或转换 - 转秒级:用
time_t中间类型,或直接用duration_cast<seconds>()</seconds> - 注意:
system_clock不保证是单调时钟,可能受系统时间调整影响(如 NTP 校正)
auto now = std::chrono::system_clock::now(); auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count(); // seconds 是 long long 类型,即标准 Unix 时间戳(秒)
获取毫秒/微秒级时间戳(需要更高精度)
很多日志、性能打点、网络协议需要毫秒或微秒粒度。仍用 std::chrono,只换 duration_cast 的目标类型即可。
- 毫秒时间戳:用
std::chrono::milliseconds,结果是自 epoch 起的毫秒数(long long) - 微秒同理,但要注意:某些平台(如 Windows)
system_clock实际分辨率只有 ~15ms,别误以为能稳定拿到微秒 - 不要用
clock_gettime(CLOCK_REALTIME, ...)手动拼——它不是标准 C++,且返回结构体需自己算
auto now = std::chrono::system_clock::now(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count(); // ms 是自 1970-01-01 起的毫秒数,可直接用于日志前缀或 HTTP Date 头构造
为什么不该用 time(nullptr)?
它看似简单,但隐藏三个实际问题:
立即学习“C++免费学习笔记(深入)”;
- 返回
time_t,类型不明确(C++11 前可能是int,32 位系统 2038 年就溢出) - 无法直接获得毫秒——你得再调
gettimeofday()或clock_gettime(),引入平台差异 -
time()是基于system_clock的封装,但丢掉了精度和类型信息,属于“退化使用”
除非你在写兼容 C99 的极简嵌入式代码,否则没理由绕开 std::chrono。
Windows 下特别注意 GetSystemTimeAsFileTime 的陷阱
有人查 MSDN 后直接用这个 API,结果发现值比 Unix 时间戳大 11644473600 秒——因为它返回的是自 1601-01-01 起的 100 纳秒单位数。
- 换算公式固定:
unix_ts = (filetime - 116444736000000000LL) / 10000000 - 但手动计算易出错,且完全失去可读性和可移植性
-
std::chrono::system_clock::now()在 MSVC 和 MinGW 下都已正确映射到系统真实时间,无需干预
真正容易被忽略的,是 system_clock::time_point 到 time_t 的转换在某些老编译器(如早期 GCC 4.8)里有符号扩展 bug;只要用 duration_cast 直接取 count(),就能绕过所有中间类型风险。











