首页 > 解决方案 > 将十进制 GPS 时间转换为 UTC

问题描述

那里有很多类似的问题,但我还没有找到一个特定于我收到的 GPS 输出数据的问题。我的 GPS 数据是十进制格式:

GPS 周:2145GPS 时间:330374.741371 (手册说这是代表“以秒为单位的一周时间”的双精度数)

我正在尝试将这个时间转换为人类可读的 UTC 时间。我使用的是旧的 C++14,而不是 20,所以我不能只使用我不认为的 to_utc() 函数。我主要对小数感到困惑。在这个网站上:https : //www.labsat.co.uk/index.php/en/gps-time-calculator 看起来数据是“secondsOfTheWeek.secondsOfTheDay。我不确定如何将其转换为 UTC 时间...

我相信这个输出数据是自 1980 年 1 月 6 日午夜 GPS 纪元时间以来的秒数。而且我知道它不计算闰秒,因此也必须考虑到这一点。如果我有一些关于如何开始进入 UTC 时间的指导,我想我可以弄清楚其余的,但我不确定从哪里开始......

最终,我想将时间转换为字符串,以使用“date -s”16 AUG 2021 13:51:00 或类似的方式设置操作系统系统的时间。但首先我只需要转换这个 GPS 时间。

标签: c++gpsc++14utcdatetime-conversion

解决方案


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_time通过将适当的周数添加到 gps 纪元,然后添加秒数来形成 a。

接下来,您将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

需要进行一些安装。

更多信息

这篇Wikipedia 文章说,一周中的时间实际上以 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函数现在采用两个严格类型的参数:一个 count ofweeks和一个 count of gps_tow。然后,只需将这些部分与 gps 纪元一起添加在一起,clock_cast就可以了utc_clock

它可以像这样使用:

cout << convert(weeks{1851}, gps_tow{172811}) << '\n';

此示例的输出为:

2015-06-30 23:59:60.5

推荐阅读