使用std :: chrono/date :: gps_clock将double gps时间戳转换为utc/tai [英] Using std::chrono / date::gps_clock for converting a double gps timestamp to utc/tai

查看:383
本文介绍了使用std :: chrono/date :: gps_clock将double gps时间戳转换为utc/tai的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从gps_data结构中的GPS设备获取时间戳记为double.

我想将此GPS时间戳转换为UTC和TAI时间,方法很简单:

void handle_gps_timestamp(double timestamp) 
{
    double utc = utc_from_gps(timestamp);
    double tai = tai_from_gps(timestamp);
    do_stuff(gps, utc, tai);
}

幸运的是,我发现 Howard Hinnant的日期和时区库(适用于C ++ 20)似乎提供了这一确切功能.不幸的是,至少从我所看到的来看,date/tz/chrono库没有方便的方法来实现这种简单的用法.

我必须首先以某种方式将我的双打转移"到已知的时间/日期类型.但是好吧,因为我了解了总体概念,即 时间点 被定义为(或之后的 持续时间 之前) 时钟 时代 ,我认为这是一个漂亮的模型.

假设

我应该能够非常轻松地转换模型以适合我的问题,对吧?

就我而言,我有一个时间戳,它是一个时间点,指定为距gps纪元以来的持续时间.现在,我想想,应该有一个时钟类可以为我抽象和处理所有这些.是的!有一个date :: gps_clock和一个date :: gps_time肯定可以完成工作.

问题

我不能让它对我有用.我敢肯定解决方案是微不足道的.

问题

有人可以帮助我,说明如何使用霍华德的日期库解决问题吗?

解决方案

正是由于未明确指定问题的输入,所以很难回答这个问题:

我从gps_data结构中的GPS设备获得一个时间戳记,将其作为double值,指定为距gps纪元以来的持续时间.

因此,我将作一些假设.我将陈述所有假设,希望可以清楚地知道如何更改关于double代表什么的其他猜测/事实的答案.

假设double是自gps时代以来毫秒的非整数计数.此外,让我们假设我想捕获此输入的精度(微秒级).

#include "date/tz.h"
#include <cstdint>
#include <iostream>

int
main()
{
    double gps_input = 1e+12 + 1e-3;
    using namespace date;
    using namespace std::chrono;
    using dms = duration<double, std::milli>;
    gps_time<microseconds> gt{round<microseconds>(dms{gps_input})};
    auto utc = clock_cast<utc_clock>(gt);
    auto tai = clock_cast<tai_clock>(gt);
    std::cout << gt << " GPS\n";
    std::cout << utc << " UTC\n";
    std::cout << tai << " TAI\n";
}

我任意创建了一个示例输入,并将其存储在gps_input中.

某些使用指令会使代码的冗长程度降低很多.

完全完全匹配的自定义chrono::duration类型,double表示的内容使很多变得更简单,并且减少了出错的机会.在这种情况下,我制作了一个chrono::duration,将milliseconds存储在double中,并将其命名为dms.

现在,您只需将double转换为dms,然后使用round,将dms转换为microseconds,然后将这些microseconds存储在精度为microseconds的gps时间点中,或者更好.可以使用duration_cast代替round,但是当从浮点数转换为整数时,我通常更喜欢round,这意味着从平到最近和到平缓. >

现在您有了gps_time,可以使用clock_cast函数将其转换为其他时间,例如utc_timetai_time.

该程序输出:

2011-09-14 01:46:40.000001 GPS
2011-09-14 01:46:25.000001 UTC
2011-09-14 01:46:59.000001 TAI

根据需要在上方调整millisecondsmicroseconds单位.例如,如果输入代表seconds,最简单的操作是将dms上的第二个模板参数默认为默认值:

using dms = duration<double>;

此库适用于C ++ 11/14/17.并进行了少量修改,现在它已成为官方C ++ 20规范的一部分.

I get a timestamp from a GPS device in a gps_data struct as a double.

I'd like to convert this GPS timestamp to UTC and TAI times, something simple as:

void handle_gps_timestamp(double timestamp) 
{
    double utc = utc_from_gps(timestamp);
    double tai = tai_from_gps(timestamp);
    do_stuff(gps, utc, tai);
}

Luckily I found Howard Hinnant's date and timezone library (proposed for C++20) that seems to provide this exact functionality. Unfortunately, at least from what I can see, the date/tz/chrono library has no convenient methods that allow this simple usage.

I must first somehow "transfer" my double into a known chrono/date type. But OK, since I understand the overall concept, namely that the timepoint is defined as a duration after (or before) the epoch of a clock, and I think that this is a beautiful model.

Assumption

I should be able to very easily translate that model to fit my problem, right?

In my case, I have a timestamp that is a point in time, specified as the duration since the gps epoch. Now, there should be a class type of a clock that abstracts and handles all of this for me, I'd like to think. And yes! There is a date::gps_clock and a date::gps_time, which surely should do the work.

Problem

I cannot make it work for me. I'm sure the solution is trivial.

Question

Can someone give me a helping hand, showing how I should use Howard's date library applied to my problem?

解决方案

It is difficult to answer this question precisely because the input to the problem is underspecified:

I get a timestamp from a GPS device in a gps_data struct as a double ... specified as the duration since the gps epoch.

Therefore I'm going to make some assumptions. I'll state all of my assumptions, and hopefully it will be clear how to alter my answer for other guesses/facts about what that double represents.

Let's say that the double is a non-integral count of milliseconds since the gps epoch. Let's furthermore assume that I want to capture the precision of this input down to microseconds.

#include "date/tz.h"
#include <cstdint>
#include <iostream>

int
main()
{
    double gps_input = 1e+12 + 1e-3;
    using namespace date;
    using namespace std::chrono;
    using dms = duration<double, std::milli>;
    gps_time<microseconds> gt{round<microseconds>(dms{gps_input})};
    auto utc = clock_cast<utc_clock>(gt);
    auto tai = clock_cast<tai_clock>(gt);
    std::cout << gt << " GPS\n";
    std::cout << utc << " UTC\n";
    std::cout << tai << " TAI\n";
}

I've arbitrarily created an example input and stored it in gps_input.

Some using directives make the code a lot less verbose.

A custom chrono::duration type that exactly matches the documented specification for what the double represents makes things much simpler, and lessens the chance for errors. In this case I've made a chrono::duration that stores milliseconds in a double and named that type dms.

Now you simply convert the double to dms, and then using round, convert the dms to microseconds, and store those microseconds in a gps time point with precision microseconds or finer. One could use duration_cast in place of round, but when converting from floating point to integral, I usually prefer round, which means round-to-nearest-and-to-even-on-tie.

Now that you have a gps_time, one can use the clock_cast function to convert to other times such as utc_time and tai_time.

This program outputs:

2011-09-14 01:46:40.000001 GPS
2011-09-14 01:46:25.000001 UTC
2011-09-14 01:46:59.000001 TAI

Adjust the milliseconds and microseconds units above as needed. For example if the input represents seconds, the easiest thing to do is to default the second template argument on dms:

using dms = duration<double>;

This library works with C++11/14/17. And with minor modifications it is now part of the official C++20 specification.

这篇关于使用std :: chrono/date :: gps_clock将double gps时间戳转换为utc/tai的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆