在C++20中,UNIX系统下(不需要可移植性),如何转换以下格式的UTC字符串日期时间:
"2024-04-26T14:33:30.185Z"
转换为 UNIX UTC 数字时间戳?
我正在寻找标准推荐方式,如果有的话。
类似问题有很多答案,但它们似乎要么为旧标准提供解决方案,要么注重可移植性,要么需要时区转换。我正在寻找一种简单有效的标准方法,可以在 Linux 下使用 C++20 执行此操作,无需可移植性要求,也无需时区转换。
在 C++20 中:
#include <chrono>
#include <iostream>
#include <sstream>
int
main()
{
std::string s = "2024-04-26T14:33:30.185Z";
std::istringstream f(std::move(s));
std::chrono::sys_time<std::chrono::milliseconds> tp;
f >> std::chrono::parse("%FT%TZ", tp);
std::cout << tp.time_since_epoch().count() << '\n';
}
输出:
1714142010185
这会将字符串解析为基于
system_clock
的 time_point
,精度为 milliseconds
。 system_clock
测量 Unix Time(自 1970-01-01 00:00:00 UTC 以来的时间,不包括闰秒)。 这是system_clock
时代的规格。
std::chrono::utc_time
与sys_time
不同仅在于它包括闰秒计数:http://eel.is/c++draft/time.clock#utc.overview-1
.time_since_epoch().count()
从中提取毫秒的整数time_point
。
不幸的是,它尚未在 gcc 中发布,但将在 gcc-14 中发布。这里存在该库的开源、免费、仅包含头文件的 pre-C++20-chrono 预览:https://github.com/HowardHinnant/date
只需包含
"date/date.h"
并将一些 std::chrono
更改为 date
。
如果您的编译器支持,您可以使用
utc_time
和 from_stream
:
const std::string value = "2024-04-26T14:33:30.185Z";
// this will truncate the milliseconds away
{
std::stringstream ss{value};
std::chrono::utc_time<std::chrono::seconds> time;
std::chrono::from_stream(ss, "%Y-%m-%dT%H:%M:%S%Z", time);
const auto unix_time_s = time.time_since_epoch().count();
std::cout << unix_time_s << "\n";
}
// this will keep the milliseconds
{
std::stringstream ss{value};
std::chrono::utc_time<std::chrono::milliseconds> time;
std::chrono::from_stream(ss, "%Y-%m-%dT%H:%M:%S%Z", time);
const auto unix_time_ms = time.time_since_epoch().count();
const auto unix_time_s_with_ms = time.time_since_epoch().count() / 1000.;
std::cout << unix_time_ms << "\n";
std::cout << std::format("{:.3f}", unix_time_s_with_ms) << "\n";
}