C++ 自定义时间日期结构到 utc 纪元
C++ custom time date struct to utc epoch
我使用一个库,该库使用以下结构来定义开始时间戳,如下所示。
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 结构的纪元创建计时、time_t 或 unix 时间,然后将纳秒添加到其中。
第一个条目的打印输出
2017-12-19 14:44:00.000397
此致
您可以使用 mktime()
从 <ctime>
将 tm
转换为 time_t
,这是一个整数类型。
tm
与您的 SYSTEMTIME
结构非常相似。因此,您应该能够轻松地来回翻译它们。
将您的结构翻译成 tm,然后像这样使用 gmtime()
。
#include <ctime>
struct tm time = fromSystemtime(...);
time_t timestamp;
timestamp = mktime(&time);
有关详细信息,请参阅以下链接:
已更新
我稍微修改了下面的代码以在 SYSTEMTIME
和 date::sys_time<std::chrono::milliseconds>
之间转换,而不是 date::sys_time<std::chrono::nanoseconds>
。
基本原理: 因此 to_SYSTEMTIME
中没有隐含的精度损失。 to_SYSTEMTIME
的客户可以以他们想要的任何方式明确地 t运行 精确度(floor
、round
、ceil
等)。未能达到 运行 精度(如果需要)不会是无声的 运行 时间错误。
客户端代码(在 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<system_clock, milliseconds>
(它有一个名为 date::sys_time<milliseconds>
的类型别名)。然后它简单地将 nanoseconds
添加到 time_point
,t运行 将其分类为 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;
}
我使用一个库,该库使用以下结构来定义开始时间戳,如下所示。
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 结构的纪元创建计时、time_t 或 unix 时间,然后将纳秒添加到其中。
第一个条目的打印输出 2017-12-19 14:44:00.000397
此致
您可以使用 mktime()
从 <ctime>
将 tm
转换为 time_t
,这是一个整数类型。
tm
与您的 SYSTEMTIME
结构非常相似。因此,您应该能够轻松地来回翻译它们。
将您的结构翻译成 tm,然后像这样使用 gmtime()
。
#include <ctime>
struct tm time = fromSystemtime(...);
time_t timestamp;
timestamp = mktime(&time);
有关详细信息,请参阅以下链接:
已更新
我稍微修改了下面的代码以在 SYSTEMTIME
和 date::sys_time<std::chrono::milliseconds>
之间转换,而不是 date::sys_time<std::chrono::nanoseconds>
。
基本原理: 因此 to_SYSTEMTIME
中没有隐含的精度损失。 to_SYSTEMTIME
的客户可以以他们想要的任何方式明确地 t运行 精确度(floor
、round
、ceil
等)。未能达到 运行 精度(如果需要)不会是无声的 运行 时间错误。
客户端代码(在 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<system_clock, milliseconds>
(它有一个名为 date::sys_time<milliseconds>
的类型别名)。然后它简单地将 nanoseconds
添加到 time_point
,t运行 将其分类为 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;
}