【问题标题】:C++ custom time date struct to utc epochC ++自定义时间日期结构到UTC时代
【发布时间】:2018-06-01 23:25:49
【问题描述】:

我使用了一个库,该库使用以下结构来定义开始时间戳,如下所示。

    struct SYSTEMTIME {
    /** year */
    WORD year;

    /** month */
    WORD month;

    /** day of week */
    WORD dayOfWeek;

    /** day */
    WORD day;

    /** hour */
    WORD hour;

    /** minute */
    WORD minute;

    /** second */
    WORD second;

    /** milliseconds */
    WORD milliseconds;
};

对于此时间之后的每个日志条目,都指定了与第一个时间戳的纳秒差异。

假设它的UTC 2017-12-19 14:44:00 之后的第一个日志条目是 397000ns。

如何从第一个 SYSTEMTIME 结构的纪元创建 chronos、time_t 或 unix 时间,然后将纳秒添加到其中。

打印输出应该是第一个条目 2017-12-19 14:44:00.000397

最好的问候

【问题讨论】:

  • 我会从另一个方向开始,从 unix 时间戳开始,如有必要,将其转换为年、月等。这可能更简单一些。
  • 不幸的是,由于我正在使用的库,这是不可能的。所以我需要构建一个 unix 时间戳才能工作。

标签: c++ c++11 timestamp chrono time-t


【解决方案1】:

更新

我稍微修改了下面的代码以在SYSTEMTIMEdate::sys_time<std::chrono::milliseconds> 之间转换,而不是date::sys_time<std::chrono::nanoseconds>

基本原理: 这样to_SYSTEMTIME 中就没有隐含的精度损失。 to_SYSTEMTIME 的客户端可以以他们想要的任何方式显式截断精度(floorroundceil 等)。并且未能截断精度(如果需要)不会是静默运行时错误。

客户端代码(main)不受此更改的影响。


您可以为此使用Howard Hinnant's free, open-source, header-only date/time library

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

using WORD = int;

struct SYSTEMTIME {
    /** year */
    WORD year;

    /** month */
    WORD month;

    /** day of week */
    WORD dayOfWeek;

    /** day */
    WORD day;

    /** hour */
    WORD hour;

    /** minute */
    WORD minute;

    /** second */
    WORD second;

    /** milliseconds */
    WORD milliseconds;
};

date::sys_time<std::chrono::milliseconds>
to_sys_time(SYSTEMTIME const& t)
{
    using namespace std::chrono;
    using namespace date;
    return sys_days{year{t.year}/t.month/t.day} + hours{t.hour} +
           minutes{t.minute} + seconds{t.second} + milliseconds{t.milliseconds};
}

int
main()
{
    using namespace std::chrono;
    using namespace date;
    SYSTEMTIME st{2017, 12, 2, 19, 14, 44, 0, 0};
    auto t = to_sys_time(st) + 397000ns;
    std::cout << floor<microseconds>(t) << '\n';
}

输出:

2017-12-19 14:44:00.000397

这通过收集SYSTEMTIME 中的不同部分,将SYSTEMTIME 转换为std::chrono::time_point&lt;system_clock, milliseconds&gt;(具有名为date::sys_time&lt;milliseconds&gt; 的类型别名)。然后它简单地将nanoseconds 添加到time_point,将其截断为microseconds 的所需精度,然后将其流出。

如果有帮助,您可以使用相同的库进行相反的转换:

SYSTEMTIME
to_SYSTEMTIME(date::sys_time<std::chrono::milliseconds> const& t)
{
    using namespace std::chrono;
    using namespace date;
    auto sd = floor<days>(t);
    year_month_day ymd = sd;
    auto tod = make_time(t - sd);
    SYSTEMTIME x;
    x.year = int{ymd.year()};
    x.month = unsigned{ymd.month()};
    x.dayOfWeek = weekday{sd}.c_encoding();
    x.day = unsigned{ymd.day()};
    x.hour = tod.hours().count();
    x.minute = tod.minutes().count();
    x.second = tod.seconds().count();
    x.milliseconds = tod.subseconds().count();
    return x;
}

【讨论】:

    【解决方案2】:

    您可以使用mktime()&lt;ctime&gt;tm 转换为time_t,这是一个整数类型。

    tm 与您的 SYSTEMTIME 结构非常相似。因此,您应该能够轻松地来回翻译它们。

    将你的结构翻译成 tm,然后像这样使用gmtime()

    #include <ctime>
    
    struct tm time = fromSystemtime(...);
    time_t timestamp;
    
    timestamp = mktime(&time);
    

    更多详情请看以下链接:

    struct tm

    time_t

    mktime

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-09
      • 2012-10-07
      • 2016-05-22
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      • 2012-01-30
      相关资源
      最近更新 更多