将日期、时间和 UTC 偏移值转换为自 unix 纪元以来的毫秒数?
Converting date, time and UTC offset values to milliseconds since unix epoch?
我正在从事一个机器人项目,该项目具有来自不同位置的传感器数据,精度为毫秒(gps 同步 ntp 到 1 毫秒以内)。
如何将历史日期、时间和UTC偏移分量转换为自unix纪元以来的毫秒数?也就是说,所有 YYYY-mm-dd HH:MM:SS.mS +/-UTC offset
都可以作为单独的整数而不是字符串使用。
夏令时的偏移量,例如,UTC +1 的时区在夏令时期间的 UTC 偏移量为 +2。
有一个 但是它处理的是字符串格式的日期时间,没有 UTC 偏移信息。
post 接受的答案是使用 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 纪元以来的毫秒数的可靠方法是什么?
如果您有以小时 +/- UTC 为单位的时区,您可以先使用 mktime
(如链接答案所述)将 date/time 转换为纪元以来的秒数。然后,add/subtract时差。
编辑:
由于 mktime
函数假定给定时间是针对当前时区的,因此您也需要将结果移动该数量。
首先,运行 tzset()
函数。这会设置两个全局变量:timezone
表示当前时间比 GMT 晚多少秒,daylight
表示夏令时是否生效。
struct tm my_time;
// populate fields
int my_tz;
// set to timezone in question as seconds ahead of UTC
time_t t = mktime(&my_time);
t += timezone;
if (daylight) {
t -= 3600;
}
t -= my_tz;
如果您查看您提到的问题的已接受答案,它涉及单个整数。它将字符串拆分为多个部分,将它们转换为整数,然后使用它们。只需删除转换部分。
tm t;
// Fill tm_sec, tm_min, tm_hour and so on
return (mktime(&t) - tz * SECONDS_IN_TIMEZONE) * 1000 + milliseconds
如果时区是一个整数,您可以将它乘以时区中的秒数,如果是从时间中减去。 +4 时区表示时间比 UTC 时间长 4 小时。另请注意,并非所有时区都具有整数小时数。因此,您可能希望将时区存储在 seconds/milliseconds 或至少几分钟内。
这是其中的一个free, open-source C++11/14 header-only library which will do the job. It is fully documented, and portable across all C++11/14 implementations. There is even a 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 milliseconds since the epoch. If you need to include leap seconds, there are facilities for that at the above links, but that part is not header-only (requires using the IANA timezone database).
的正确数字是哪个
此库是基于 <chrono>
的。特别是 tp
的类型是 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>
,但语法更漂亮。
如果您的输入流遵循 +/-hhmm 的标准 UTC 偏移语法而不是 +/-[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
我正在从事一个机器人项目,该项目具有来自不同位置的传感器数据,精度为毫秒(gps 同步 ntp 到 1 毫秒以内)。
如何将历史日期、时间和UTC偏移分量转换为自unix纪元以来的毫秒数?也就是说,所有 YYYY-mm-dd HH:MM:SS.mS +/-UTC offset
都可以作为单独的整数而不是字符串使用。
夏令时的偏移量,例如,UTC +1 的时区在夏令时期间的 UTC 偏移量为 +2。
有一个
post 接受的答案是使用 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 纪元以来的毫秒数的可靠方法是什么?
如果您有以小时 +/- UTC 为单位的时区,您可以先使用 mktime
(如链接答案所述)将 date/time 转换为纪元以来的秒数。然后,add/subtract时差。
编辑:
由于 mktime
函数假定给定时间是针对当前时区的,因此您也需要将结果移动该数量。
首先,运行 tzset()
函数。这会设置两个全局变量:timezone
表示当前时间比 GMT 晚多少秒,daylight
表示夏令时是否生效。
struct tm my_time;
// populate fields
int my_tz;
// set to timezone in question as seconds ahead of UTC
time_t t = mktime(&my_time);
t += timezone;
if (daylight) {
t -= 3600;
}
t -= my_tz;
如果您查看您提到的问题的已接受答案,它涉及单个整数。它将字符串拆分为多个部分,将它们转换为整数,然后使用它们。只需删除转换部分。
tm t;
// Fill tm_sec, tm_min, tm_hour and so on
return (mktime(&t) - tz * SECONDS_IN_TIMEZONE) * 1000 + milliseconds
如果时区是一个整数,您可以将它乘以时区中的秒数,如果是从时间中减去。 +4 时区表示时间比 UTC 时间长 4 小时。另请注意,并非所有时区都具有整数小时数。因此,您可能希望将时区存储在 seconds/milliseconds 或至少几分钟内。
这是其中的一个free, open-source C++11/14 header-only library which will do the job. It is fully documented, and portable across all C++11/14 implementations. There is even a 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 milliseconds since the epoch. If you need to include leap seconds, there are facilities for that at the above links, but that part is not header-only (requires using the IANA timezone database).
的正确数字是哪个此库是基于 <chrono>
的。特别是 tp
的类型是 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>
,但语法更漂亮。
如果您的输入流遵循 +/-hhmm 的标准 UTC 偏移语法而不是 +/-[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