c++ - 将日期、时间和 UTC 偏移值转换为自 unix 纪元以来的毫秒数?

标签 c++ c linux datetime epoch

我正在从事一个机器人项目,该项目具有来自不同位置的传感器数据,精度为毫秒(gps 同步 ntp 到 1 毫秒以内)。

如何将历史日期、时间和 UTC 偏移分量转换为自 unix 纪元以来的毫秒数?也就是说,所有 YYYY-mm-dd HH:MM:SS.mS +/-UTC 偏移量 都可以作为单独的整数而不是字符串使用。

夏令时的偏移量,例如,UTC +1 的时区在夏令时期间的 UTC 偏移量为 +2。

有一个similar post然而,它处理的是没有 UTC 偏移信息的字符串格式的日期时间。

该帖子接受的答案是使用 mktime 但是在 this post 中一位 60K+ 代表用户评论说:

mktime will use your computer's locale to convert that date/time into GMT. If you do not want to have your local timezone subtracted, then use mkgmtime.

我已经确认 mktime 确实执行了取决于夏令时标志 tm_isdst 的时区转换。我不知道这些观察是否是在夏令时期间进行的,只有它们对 UTC 的偏移量。

将具有 UTC 偏移量的历史日期时间转换为自 unix 纪元以来的毫秒数的稳健方法是什么?

最佳答案

这是一个可以完成这项工作的 free, open-source C++11/14 header-only library。它是 fully documented ,并且可以跨所有 C++11/14 实现移植。甚至还有它的 video presentation

#include "chrono_io.h"
#include "date.h"
#include <iostream>
#include <sstream>

int
main()
{
    using namespace std;
    using namespace std::chrono;
    using namespace date;
    istringstream in{"2016-10-10 23:48:59.456 -4"};
    sys_time<milliseconds> tp;
    int ih;
    in >> parse("%F %T", tp) >> ih;
    tp -= hours{ih};
    cout << tp.time_since_epoch() << '\n';
}

这个输出:

1476157739456ms

这是自纪元以来的正确 Unix Time 毫秒数。如果您需要包括闰秒,在上面的链接中有相应的工具,但该部分不是仅标题(需要使用 IANA timezone database )。

这个库是基于 <chrono> 的。特别是 tp 的类型是 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> ,但语法更漂亮。

如果您的输入流遵循标准的 UTC 偏移语法 +/-hhmm 而不是 +/-[h]h,则代码可以简化为:

istringstream in{"2016-10-10 23:48:59.456 -0400"};
sys_time<milliseconds> tp;
in >> parse("%F %T %z", tp);

这将为 tp 输出完全相同的值。

1476157739456ms

也支持这种修改后的语法:

istringstream in{"2016-10-10 23:48:59.456 -4:00"};
sys_time<milliseconds> tp;
in >> parse("%F %T %Ez", tp);

如果你想要毫秒的整数值,可以使用 <chrono>duration.count() 成员函数:

cout << tp.time_since_epoch().count() << '\n';

1476157739456

无论您如何分割,这都是几行类型安全的代码,没有明确的转换因子。

我注意到你用 [c++] 和 [c] 标记了你的问题。此答案仅针对 C++ 语言。 C 和 C++ 是两种截然不同的语言,如果您必须使用 C 进行编程,那么在 C 抽象级别进行编程的其他答案之一会更好。

出于好奇,对于这些变体中的任何一个,如果您只是输出 tp :

cout << tp << '\n';

然后它输出预期的 UTC 时间戳:

2016-10-11 03:48:59.456

关于c++ - 将日期、时间和 UTC 偏移值转换为自 unix 纪元以来的毫秒数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39963727/

相关文章:

c++ - "macro names must be identifiers"

C++递归重复输出

c++ - 为什么 char *x 而不是 char x?

capset 因指向结构的指针而失败

linux - 使用文本文件的 Perl 代码

c++ - 为什么在asio的示例中,tcp接受器模式使用shared_pointer模型包装堆套接字,而udp使用堆栈套接字?

c - 我不能使用 <nameofmystructure>* this 作为函数的参数

C pthread 从多个线程访问数组

linux - 有没有办法在 Fortinet CLI 中运行 bash 命令?

Linux Git SSH key 授权失败