c++oding="utf-8" ?>
std::chrono::tai_clock 在 gcc 13、clang 17、msvc 19.38 等主流实现中均未提供,因其为标准中 conditionally supported 特性,需维护动态闰秒表而被厂商回避;应改用 utc_clock 加手动查表转换。

std::chrono::tai_clock 在绝大多数 C++20 实现中不可用,不是你代码写错了,而是标准库根本没实现它。
为什么 tai_clock 编译失败或找不到
C++20 标准确实在 <chrono></chrono> 中“声明”了 std::chrono::tai_clock,但它被定义为 optional —— 即实现可选择不提供。目前(截至 GCC 13、Clang 17、MSVC 19.38),所有主流标准库均未实现该时钟。调用 tai_clock::now() 会触发编译错误(如 “‘tai_clock’ is not a member of ‘std::chrono’”)或链接失败。
- 标准原文明确标注其为
Conditionally supported,且要求实现若支持,必须满足 UTC-TAI 偏移可查(即需维护闰秒表) - 真实天文时间处理依赖外部数据源(如 IERS 发布的闰秒文件),标准库不愿/无法内置此逻辑
- 即使你看到某些文档或头文件里有声明,那只是空壳声明(
extern template或 SFINAE 预留),不代表可运行
替代方案:用 utc_clock + 手动闰秒表模拟 TAI
如果你真需要 TAI 时间(例如射电天文观测、卫星轨道推算),实际做法是:用已实现的 std::chrono::utc_clock 获取 UTC 时间点,再查表加上当前 UTC-TAI 偏移(单位为秒)。这个偏移值随闰秒插入而变化,不能硬编码。
-
utc_clock已在 libstdc++(GCC 13+)、libc++(Clang 17+)中实现,但需启用-std=c++20且确保系统时区数据库支持(Linux 上通常 OK) - 闰秒表必须定期更新;IERS 官网每半年发布一次新文件(
leap-seconds.list),需自行解析并缓存 - 简单示例:假设已知 2024 年 UTC-TAI = +37s,则
auto tai_tp = std::chrono::utc_clock::now() + std::chrono::seconds(37); - 注意:UTC 时间点本身可能因系统时钟未同步(NTP 失效)而偏差数秒,TAI 推算结果精度直接受限于此
别碰 system_clock 当 TAI 用
有人试图把 std::chrono::system_clock::now() 当作 TAI 用——这是危险的误解。system_clock 在 POSIX 系统上通常等价于 Unix time(即自 1970-01-01T00:00:00 UTC 起的秒数,忽略闰秒),它和 TAI 既无固定偏移,也不随闰秒调整。
- Unix time 和 TAI 的差值一直在变(当前约 +37s,但下次闰秒后变成 +38s)
- 用
system_clock构造“TAI 时间点”会导致时间戳在闰秒发生后漂移 1 秒,对高精度任务(如 VLBI 相关器时间戳)不可接受 - 更糟的是:不同平台对
system_clock::time_since_epoch()的 epoch 解释可能不同(Windows 下甚至不是 Unix epoch)
真正需要 TAI 时,推荐组合方案
生产环境处理天文时间,不要只靠标准库。务实路径是:utc_clock 读取高精度 UTC,配合轻量级闰秒数据库(如 tzdb 的 leapseconds 数据),再用 std::chrono::time_point 手动加减。
- 避免自己解析
leap-seconds.list:用现成库如date::get_tai_offset()(Howard Hinnant 的 date 库,已合并进 libc++ 实验性支持) - 若需纳秒级精度,确保硬件时钟已通过 PTP 或 GPSDO 校准,否则软件层再准也没用
- 记住:C++ 标准不保证任何时钟的绝对精度,只规定语义。TAI 的“高精度”最终取决于你的授时源,而非
tai_clock是否存在
别浪费时间在让 tai_clock 工作上——它现在不存在,短期内也不会有。重点放在怎么可靠获取 UTC 并查表转 TAI,这才是真实项目里跑得通的路。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











