C++标准库不支持闰秒,所有时间类型均基于抹平闰秒的Unix时间;需依赖IERS发布的闰秒表(如bulletinc.dat)或第三方库(如libtai、tzdb)进行查询与转换。

闰秒在C++里根本没法直接判断
标准C++库(包括<chrono>、<ctime>)完全不提供闰秒支持。所有std::time_t、std::chrono::system_clock和std::tm都基于Unix时间(即TAI减去固定TAI-UTC偏移1972年1月1日的值),把闰秒“抹平”了——比如2016年12月31日23:59:60这个真实存在的时刻,在time_t中根本不存在,它被映射成两个连续的秒(或跳过),具体行为取决于系统实现。
想查某天有没有闰秒?得靠外部权威列表
国际地球自转服务(IERS)每半年发布一次闰秒公告,明确给出生效日期和方向(正闰秒+1s,目前只有+1s)。C++程序不能自己“算”出哪天有闰秒,只能查表比对。
- 官方来源是IERS的
bulletinc.dat文件,每行格式如:2016 12 31 23 59 60 + - 实际项目中更常用的是预编译好的C/C++头文件,例如tzdb的
leapseconds文件,或第三方库如libtai、cpp-httplib配合HTTP拉取 - 注意:闰秒只发生在6月30日或12月31日23:59:60,其他日期直接返回false即可
用std::chrono做时间转换时,闰秒会静默丢失
哪怕你手动构造一个“23:59:60”的std::tm并传给mktime(),大多数libc(glibc、musl)会将其归一化为次日00:00:00,或者返回-1。这不是bug,是设计使然。
-
mktime({.tm_sec=60, .tm_min=59, .tm_hour=23, ...})→ 返回-1或修正为00:00:00 -
std::chrono::system_clock::to_time_t()永远输出整数秒,不可能表示闰秒点 - 若需高精度TAI/UTC转换,必须引入外部闰秒表+算法(如
leapsecond.cpp里的插值逻辑),不能依赖标准库
生产环境建议:别自己解析闰秒,用成熟库
自己维护闰秒列表极易出错(比如忘记更新、时区混淆、误判生效时间)。真正需要处理闰秒的场景(天文观测、金融高频时间戳、卫星导航)几乎都用现成方案:
立即学习“C++免费学习笔记(深入)”;
- Linux上可读取
/usr/share/zoneinfo/leap-seconds.list(需root权限且不一定存在) - C++20起,
<chrono>新增utc_clock和tai_clock,但要求标准库实现支持闰秒——目前GCC、Clang均未启用,MSVC不支持 - 最稳妥的是用
libical或Rust写的chrono-tz通过FFI调用,或干脆用Python的astropy.time做后端
闰秒不是“某个日期是否包含”,而是“UTC时间线在特定瞬时点是否插入1秒”。这个瞬时点本身无法用标准C++时间类型精确表达,硬要实现只会陷入时区、DST、系统clock drift的连环坑里。


















