我正在尝试使用日期(https://howardhinnant.github.io/date/date.html)库将数据/时间字符串转换为属于特定时区的日期/时间。
我正在用这个:
std::string t = "2024-01-02T14:42:27";
std::stringstream str(t);
std::chrono::time_point< std::chrono::system_clock, std::chrono::seconds > src_timestamp;
date::from_stream( str, "%Y-%m-%dT%H:%M:%S", result );
const auto src_tz = locate_zone(std::string("CET"));
auto zoned_src_timestamp = make_zoned(src_tz, src_timestamp);
std::cout << zoned_src_timestamp.get_local_time() << " TZ\n";
当我打印 zoned_src_timestamp.get_local_time() 时,我希望看到我的当地时间,但我得到的是“2024-01-02 15:42:27”。这不是我期待的当地时间。
我正在尝试将日期/时间字符串解析为 time_point 并将其与时区一起使用以获得可以转换为不同时区的本地时间。
我正在尝试将日期/时间字符串解析为 time_point 并将其与时区一起使用以获得可以转换为不同时区的本地时间。
std::string t = "2024-01-02T14:42:27";
std::stringstream str(t);
到目前为止一切顺利。但我将“与时区一起使用”解释为“将时间解析为时区中的当地时间”,即“CET”。为此,
src_timestamp
的类型必须是 local_time
实例化,而不是 sys_time
实例化。
sys_time
是基于 time_point
的 system_clock
系列,始终表示 Unix Time。 local_time
表示尚未与特定 time_zone
配对的当地时间。秒精度有一个特定的类型别名,称为 local_seconds
,可以方便使用:
date::local_seconds src_timestamp;
如果您更喜欢另一种精度,例如
milliseconds
,那么那就是:
date::local_time<std::chrono::millliseconds> src_timestamp;
然后用
local_time
: 进行解析
date::from_stream( str, "%Y-%m-%dT%H:%M:%S", src_timestamp );
如果您将其打印回来,您将得到完全相同的时间。现在用它来创建一个具有所需
zoned_time
的 time_zone
。您可以使用 time_zone const*
或字符串来指定 time_zone
:
auto zoned_src_timestamp = date::zoned_time("CET", src_timestamp);
这假设 C++17 或更高版本。
make_zoned
对于 C++11/14 来说很方便,因为它可以解决缺乏 CTAD 的问题。
zoned_src_timestamp
的构造创建了{time_zone const*, sys_time}
的对数据结构。 sys_time
是在构造时使用 time_zone const*
将 local_time
转换为 sys_time
来计算的。如果您询问此对象的当地时间:zoned_src_timestamp.get_local_time()
,那么它只会将 sys_time
转换回您用来构造它的 local_time
。
还可以用
zoned_time
构造 sys_time
,在这种情况下,在构造时可以避免转换为本地,并且只需存储 sys_time
。
一个人还可以用
另一个
zoned_time
构造一个 zoned_time
。我相信这就是您正在寻找的:
auto zoned_local_timestamp = date::zoned_time{date::current_zone(),
zoned_src_timestamp};
这使用
current_zone()
作为 time_zone
,并使用 zoned_src_timestamp
作为“时间戳”。
current_zone()
只是将 time_zone const*
返回到您的计算机当前设置的本地时区。
使用
zoned_src_timestamp
进行构造,使用其 sys_time
来构造新的 zoned_time
,以便两个 zoned_time
代表同一时刻,尽管位于(可能)不同的时区。 IE。它们具有相同的 UTC 时间,但当地时间不同。
然后就可以从
zoned_local_timestamp
中获取当地时间:
std::cout << zoned_local_timestamp.get_local_time() << " TZ\n";
zoned_time
只是一个方便的包装。您也可以直接使用 time_zone
来完成同样的事情:
std::string t = "2024-01-02T14:42:27";
std::stringstream str(t);
date::local_seconds src_timestamp;
date::from_stream( str, "%Y-%m-%dT%H:%M:%S", src_timestamp );
auto utc_timestamp = date::locate_zone("CET")->to_sys(src_timestamp);
auto local_timestamp = date::current_zone()->to_local(utc_timestamp);
std::cout << local_timestamp << " TZ\n";
当您想要使用 UTC 偏移量或时区缩写进行格式化时,zoned_time
变得更加方便,因为 zoned_time
将有关 time_zone
/local_time
组合的所有信息收集到单个对象中。
zoned_time
在通用代码中也会更方便,其中“时间戳”可以是 sys_time
或 local_time
。