【问题标题】:Converting a decimal GPS time to UTC将十进制 GPS 时间转换为 UTC
【发布时间】:2021-07-22 06:45:50
【问题描述】:

那里有许多类似的问题,但我没有找到一个特定于我收到的 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时间。

【问题讨论】:

  • 您在GPS Week Number Rollover 有一些提示。将翻转日期输入您显示的计算器,应该可以计算出来。

标签: c++ gps c++14 utc datetime-conversion


【解决方案1】:

有一个 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

【讨论】:

    猜你喜欢
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    • 2015-03-12
    • 1970-01-01
    • 2013-03-23
    • 2020-12-07
    相关资源
    最近更新 更多