tai_clock不是更准的system_clock,而是独立于UTC、无闰秒、与UTC偏移量随历史闰秒插入动态变化的时间标度;其now()返回以1970-01-01 TAI为起点的time_point,跨时钟转换必须通过from_utc/to_utc查闰秒表,不可手动加减固定秒数。

tai_clock 不是“更准的 system_clock”,它是完全独立的时间标度——没有闰秒、不随地球自转调整、与 UTC 固定偏移 37 秒(截至 2026 年 4 月)。直接用 system_clock::now() 加减 37 秒来模拟 TAI 是错的,因为闰秒插入历史会影响回溯转换。
为什么不能手动加减 37 秒?
TAI 和 UTC 的差值不是常量:1972 年初为 +10 秒,之后每次插入闰秒就 +1。截至 2026 年 4 月,已累计插入 27 次闰秒(含 1972 年那 10 秒),所以当前差值为 +37 秒。但 tai_clock::from_utc() 和 tai_clock::to_utc() 会查闰秒数据库,自动处理历史跳变点。手动硬编码 37 秒只对“现在”近似成立,对过去或未来时间点会出错。
- 错误示例:
auto taitp = std::chrono::time_point<tai_clock>(utc_tp.time_since_epoch() + std::chrono::seconds(37));</tai_clock>—— 这忽略所有闰秒插入时刻的不连续性 - 正确路径必须走
tai_clock::from_utc(utc_tp)或tai_clock::to_utc(tai_tp) - 闰秒数据库依赖系统时区数据(Windows 10 1809+/Linux glibc ≥2.30),旧系统可能 fallback 到静态表,结果不一致
tai_clock::now() 返回的是什么?
tai_clock::now() 返回的是当前国际原子时对应的时间点,类型为 std::chrono::time_point<tai_clock></tai_clock>,其 epoch 是 1970-01-01 00:00:00 TAI(注意:不是 UTC)。这个时间点内部用纳秒级 tai_clock::duration 表示,和 system_clock 的 epoch 起始不同,不能直接比较或算术运算。
- 不能写:
tai_clock::now() > system_clock::now()—— 编译失败,类型不兼容 - 如需比较,必须先转换:
tai_clock::to_utc(tai_tp) > system_clock::now() -
tai_clock::now()在多数实现中基于硬件原子钟信号或 NTP 校准的 TAI 源,但标准不保证精度,实际取决于平台支持
跨时钟转换必须用 from_utc / to_utc
TAI 与其他时钟(system_clock、utc_clock、gps_clock)之间没有隐式转换,所有转换都必须显式调用静态成员函数。这些函数会触发闰秒表查询,失败时抛出 std::runtime_error(例如数据库缺失或时间超出已知闰秒范围)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- UTC → TAI:
auto tai_tp = tai_clock::from_utc(utc_tp); - TAI → UTC:
auto utc_tp = tai_clock::to_utc(tai_tp); - system_clock → TAI:先转
utc_clock,再转tai_clock:tai_clock::from_utc(utc_clock::from_sys(sys_tp)) - 转换失败常见于 Windows 7 或未更新 tzdb 的嵌入式系统,建议加 try/catch
file_clock 和 tai_clock 没有直接关系
有人误以为 file_clock 时间戳可直接喂给 tai_clock,这是错的。file_clock 映射的是文件系统原生时间(如 NTFS 的 UTC 微秒、ext4 的纳秒 since epoch),它本身不携带时区或闰秒语义。它的 to_sys() 返回 system_clock::time_point,再经 utc_clock::from_sys() → tai_clock::from_utc() 才能进 TAI 域。
- 错误链:
file_clock::now() → tai_clock::from_utc(...)—— 类型不匹配,编译不过 - 正确链:
auto fc = file_clock::now(); auto sc = file_clock::to_sys(fc); auto uc = utc_clock::from_sys(sc); auto tc = tai_clock::from_utc(uc); - 每一步都可能失败,尤其在 FAT32 等无纳秒精度的文件系统上,
file_clock::to_sys()可能截断精度
真正难的不是调用 tai_clock::now(),而是理解它不提供“绝对真实时间”——它只是 TAI 标度上的一个点;所有跨标度转换都依赖外部闰秒数据,而这份数据在不同平台、不同 libc 版本、不同 Windows 更新状态下差异很大。别绕过 from_utc 直接手算,那是给自己埋定时精度 bug。

















