有一个 free, open-source preview to the C++20 chrono bits 可以与 C++14 一起使用。
#include "date/tz.h"
#include <chrono>
date::utc_seconds
convert(int gps_week, double gps_time)
{
using namespace date;
using namespace std::chrono;
int upper = static_cast<int>(gps_time);
auto gps_t = gps_seconds{} + weeks(gps_week) + seconds{upper};
return clock_cast<utc_clock>(gps_t);
}
这首先通过将适当的周数添加到 gps 纪元,然后添加秒数来形成 gps_time。
接下来,您使用clock_cast 将其转换为utc_time(其中确实包括闰秒)。
可以这样使用:
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
cout << convert(2145, 330374.741371) << '\n';
}
哪些输出:
2021-02-17 19:45:56
clock_cast 将纪元从 1980-01-06 更改为 1970-01-01,并添加了 gps 纪元和 UTC 时间点之间发生的闰秒数。如果 gps 输入恰好对应于闰秒,则会在秒字段中正确打印“60”。例如:
cout << convert(1851, 259216) << '\n'; // 2015-06-30 23:59:60
Some installation is required.
更多信息
Wikipedia article 表示一周中的时间实际上以 1.5 秒为单位,值范围从 0 到 403,199。
static_assert(403'200 * 1.5 == 7 * 24 * 60 * 60);
如果发现自己在处理这种形式的数据,这里有一个替代的convert 实现,它可以直接处理这个输入数据:
using gps_tow = std::chrono::duration<int, std::ratio<3, 2>>;
auto
convert(date::weeks gps_week_num, gps_tow tow)
{
using namespace date;
return clock_cast<utc_clock>(gps_seconds{} + gps_week_num + tow);
}
第一步是定义 1.5 秒的持续时间单位。这种类型在上面称为gps_tow。
convert 函数现在采用两个严格类型化的参数:计数weeks 和计数gps_tow。然后只需将这些部分与 gps epoch 一起添加,clock_cast 将其添加到 utc_clock。
可以这样使用:
cout << convert(weeks{1851}, gps_tow{172811}) << '\n';
这个例子的输出是:
2015-06-30 23:59:60.5