std::chrono::leap_second 在 C++20 中并不存在,它未被纳入 ISO/IEC 14882:2020 标准,所有主流标准库均不提供;闰秒在 std::chrono 中无原生支持,utc_clock 等仅依赖静态闰秒表做偏移计算,且实现不完整。

std::chrono::leap_second 在 C++20 中根本不可用
截至 C++20 标准正式发布(ISO/IEC 14882:2020),std::chrono::leap_second 并未被纳入标准库。它曾出现在早期草案(如 N4868)的讨论中,但最终被移除。所有主流标准库实现(libstdc++、libc++、MSVC STL)均不提供该类型或相关设施。
如果你在文档或代码中看到 std::chrono::leap_second,大概率是误传、过时草案引用,或某家私有扩展(非标准)。编译器会直接报错:error: 'leap_second' is not a member of 'std::chrono'。
闰秒在 std::chrono 中没有原生支持
std::chrono 的设计哲学是“基于稳定时钟”,所有时钟(system_clock、steady_clock、utc_clock 等)都假设时间流是单调、连续、无跳变的。闰秒引入的 1 秒停顿或重复,与这一模型冲突。
即使 C++20 引入了 utc_clock 和 tai_clock,它们也仅通过转换规则(如 IERS 公布的闰秒表)做静态偏移计算,不自动感知实时闰秒事件:
立即学习“C++免费学习笔记(深入)”;
-
utc_clock::to_sys()和utc_clock::from_sys()依赖编译时或运行时加载的闰秒表(如leap-seconds.list),但标准未规定如何加载或更新 - libc++ 和 MSVC STL 当前完全未实现
utc_clock的闰秒转换逻辑;libstdc++(GCC 13+)提供了实验性支持,但需手动提供闰秒文件且不处理未来闰秒公告 - 调用
utc_clock::now()返回的是基于历史已知闰秒修正过的 UTC 时间,无法反映即将发生的闰秒插入
实际项目中处理闰秒的可行路径
真正在意闰秒精度(如天文台、高频金融系统、卫星地面站)的场景,必须脱离 std::chrono 单一抽象,结合外部数据源和明确策略:
- 定期下载并解析 IERS 官方
leap-seconds.list(文本格式,含 TAI-UTC 偏移及生效时间戳),自行构建查找表 - 使用成熟第三方库替代:如 Howard Hinnant's date library(已集成闰秒表支持,提供
utc_clock可用实现) - 关键服务部署时,依赖操作系统级闰秒处理:Linux 上可通过
adjtimex()或chrony的leapsec指令同步;应用层只需信任clock_gettime(CLOCK_REALTIME)输出(前提是系统已正确配置) - 绝大多数业务系统应主动忽略闰秒——NTP 服务器通常采用 smearing(闰秒涂抹)策略平滑过渡,
system_clock::now()返回的时间已隐式处理,无需额外逻辑
为什么别自己实现 leap_second 类型
试图封装一个“能感知闰秒”的时钟类型,会立刻陷入几个现实困境:
- 闰秒发生时间由 IERS 提前约 6 个月公告,硬编码逻辑必然过期;动态加载又需文件 I/O 和线程安全更新机制
- POSIX
time_t和 Unix time 本身不表示闰秒(23:59:60是无效值),所有基于time_t的 API(strftime、mktime)都不支持秒字段为 60 - 跨平台行为不一致:Linux 内核对闰秒的处理方式(drop vs smear)取决于发行版和 NTP 实现;Windows 不支持闰秒,
GetSystemTimeAsFileTime直接跳过 23:59:60 - 测试困难:无法可靠模拟闰秒时刻,单元测试极易变成维护负担
真正需要闰秒语义的系统,早已在基础设施层(NTP daemon、kernel、硬件时钟)做了统一处理,上层 C++ 代码保持对 system_clock 或 utc_clock(来自 date lib)的简单调用即可——把复杂性留给更靠近硬件和协议的地方。


















