c++标准库(截至c++23)未定义std::chrono::gps_clock;iso c++20仅提供system_clock、utc_clock和tai_clock,gps时间需通过utc_clock或tai_clock手动偏移(当前utc−gpst=18s)计算,不可用system_clock模拟。

std::chrono::gps_clock 在 C++20 中并不存在
标准 C++ 库(截至 C++23)**没有定义 std::chrono::gps_clock**。你看到的这个名称,大概率来自某些嵌入式 SDK、第三方时间库(如 [leapseconds](https://www.php.cn/link/abe26c6ace59013c7c366a84290c2aac) 的非官方扩展)、或对 std::chrono::tai_clock/std::chrono::utc_clock 的误称。
ISO C++20 引入了三个系统时钟:std::chrono::system_clock(本地系统时间)、std::chrono::utc_clock(协调世界时 UTC,含闰秒)和 std::chrono::tai_clock(国际原子时 TAI,无闰秒)。GPS 时间(GPST)与 TAI 固定相差 19 秒(TAI = GPST + 19 s),且自 1980-01-06 00:00:00 UTC 起不引入闰秒。
所以,想用标准 C++ 处理 GPS 时间,得靠手动偏移 + utc_clock 或 tai_clock 配合已知的闰秒表。
用 std::chrono::utc_clock + 固定偏移模拟 GPST
GPS 时间从 1980-01-06 00:00:00 UTC 开始计数,且不跟随 UTC 的闰秒调整。因此,在任意时刻,GPST ≈ UTC − 18 s(因为 GPST 领先 UTC 18 秒,而 UTC 自 1980 年起累计插入了若干闰秒;当前(2024)UTC 比 GPST 快 18 秒)。
但注意:这个差值会随未来闰秒更新而变化。截至 2024 年底,UTC − GPST = 18 s;该值在每次 IERS 发布新闰秒后需手动更新。
-
std::chrono::utc_clock可读取带闰秒语义的 UTC 时间点,但标准库不提供直接转 GPST 的成员函数 - 要得到 GPST 时间点,可先获取
utc_clock::now(),再减去当前 UTC−GPST 偏移量(例如18s) - 转换为 GPST 秒数(自 1980-01-06):需将结果
time_point转为duration相对于utc_clock::time_point{},再减去 1980-01-06 对应的 UTC 纪元偏移(约 315964800s) - 实际工程中更推荐使用已校准的外部 GPS 接收器输出的原始周数+秒数,而非依赖系统时钟推算 GPST
为什么不能直接用 system_clock 模拟 GPST
std::chrono::system_clock 通常实现为 Unix 时间(自 1970-01-01 00:00:00 UTC),它忽略闰秒,且不同平台行为不一致(Linux 可能用 CLOCK_REALTIME,Windows 用 GetSystemTimeAsFileTime)。
用 system_clock 推算 GPST 会引入两层误差:
- Unix 时间本身不反映闰秒,与 UTC 已有潜在偏差(尤其在闰秒发生后短时间内)
- 1970–1980 间发生的闰秒未被计入,导致 1980-01-06 的 Unix 时间戳(315964800)是“平滑”值,无法直接用于 GPST 起点对齐
- 若系统时钟未通过 NTP/GPS 校准,其绝对误差可能达数百毫秒甚至更大,远超 GPS 定位所需的时间精度(常要求
真正需要 GPST 时该怎么做
如果你在开发 GNSS 接收器驱动、RTK 定位模块或高精度授时应用,别试图纯软件模拟 GPST —— 标准 C++ 不支持,且精度和可靠性达不到要求。
- 优先解析 GPS 接收器串口/NMEA 输出中的
$GPGGA或$GPRMC字段,提取UTC 时间 + GPS 周数,再组合成 GPST 时间点 - 使用专业库如 Howard Hinnant 的
date库(配合leapseconds.h),它提供clock_cast和完整闰秒表,可安全地在utc_clock和自定义 GPST 逻辑之间转换 - 硬件级方案:让 FPGA/ARM SoC 的定时器直接锁相到 GPS 1PPS 信号,并用接收器提供的周内秒(TOW)计数生成本地 GPST 计数器,C++ 只负责读取寄存器值
标准库里没有 gps_clock,不是遗漏,而是 GPS 时间属于领域特定语义 —— 它必须绑定真实接收器数据或权威闰秒表,没法靠通用时钟抽象兜住。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











