推荐用 std::chrono::steady_clock 获取高精度小数秒,因其单调、跨平台、纳秒级精度;取 time_since_epoch() 的纳秒数对 1e9 取模后转 double 除以 1e9,比直接 duration 更准。

用 std::chrono::steady_clock 获取高精度小数秒(推荐)
标准库中 std::chrono::steady_clock 是获取当前时间最可靠、跨平台且支持纳秒级精度的选择。它不随系统时钟调整跳变,适合测时和计算小数秒部分。
关键思路:取当前时间点,转换为自纪元起的纳秒数,再对一秒取模,最后除以 1e9 得到小数秒(double 类型)。
-
std::chrono::steady_clock::now()返回time_point,精度取决于平台(通常为纳秒或微秒) - 用
duration_cast<nanoseconds></nanoseconds>转成整数纳秒,避免浮点舍入误差 - 对
1'000'000'000取模后转double,再除以1e9,比直接用duration<double></double>更准
auto now = std::chrono::steady_clock::now(); auto ns = std::chrono::duration_cast<:chrono::nanoseconds>(now.time_since_epoch()).count(); double fractional = (ns % 1'000'000'000) / 1e9; // fractional ∈ [0.0, 1.0) </:chrono::nanoseconds>
用 std::chrono::system_clock 获取带时区的小数秒(需注意纪元差异)
如果需要与系统本地时间或 UTC 时间对齐(比如日志打点),应选 std::chrono::system_clock。但要注意:它的 time_since_epoch() 是 UTC 纪元(1970-01-01 00:00:00 UTC),不是本地时间。
- 若只取小数秒部分,
system_clock和steady_clock的结果在同一次调用中几乎一致(误差在纳秒级) - 但
system_clock可能被系统管理员手动调整或 NTP 同步跳变,导致小数秒“倒流”或突变 - Windows 上
system_clock精度常为 15–16ms,Linux/macOS 通常为纳秒级
auto now = std::chrono::system_clock::now(); auto us = std::chrono::duration_cast<:chrono::microseconds>(now.time_since_epoch()).count(); double fractional = (us % 1'000'000) / 1e6; </:chrono::microseconds>
别用 std::time(nullptr) 或 gettimeofday() 拿小数秒
这些 C 风格接口返回的是秒级整数(time_t)或最多微秒精度(struct timeval),不仅精度低,而且容易踩坑:
-
std::time(nullptr)完全没有小数部分,只能配合clock_gettime(CLOCK_MONOTONIC, ...)才行,但跨平台差 -
gettimeofday()已被 POSIX 标准标记为废弃,macOS 13+ 默认禁用,Windows 不原生支持 - 即使可用,
tv_usec字段是整数微秒,强制转double再除以1e6会丢失末尾精度(如 123456 → 0.123456,但真实值可能是 0.123456789)
注意浮点表示误差和输出截断问题
小数秒本质是整数纳秒对 1e9 取模后的有理数,但用 double 表示时,大部分值无法精确存储(例如 0.1)。实际使用中:
- 打印时建议用
std::setprecision(9)并固定小数位,否则默认精度可能只显示 6 位(如 0.123456 而非 0.123456789) - 做时间差比较时,优先用整数纳秒运算,避免
double相减引入误差 - 如果只要毫秒级,直接用
duration_cast<milliseconds></milliseconds>+% 1000更安全
真正难的不是“怎么拿”,而是“拿完怎么用不出错”——尤其当多个线程并发读取、或用于定时器调度时,steady_clock 的单调性比“看起来更真实”的 system_clock 更重要。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











