如何从C++数据库中使用make_zoned?

9avjhtql  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(150)

我尝试使用date(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,并将其与时区一起使用,以获得可以转换为不同时区的本地时间。

1u4esq0p

1u4esq0p1#

我尝试将日期/时间字符串解析为time_point,并将其与时区一起使用,以获得可以转换为不同时区的本地时间。

std::string t = "2024-01-02T14:42:27";
std::stringstream str(t);

字符串
到目前为止一切都很好。但我将“与时区一起使用”解释为“将时间解析为时区中的本地时间”,即“CET”。要做到这一点,src_timestamp的类型必须是local_time示例化,而不是sys_time示例化。
sys_time是基于system_clocktime_point系列,始终表示Unix Timelocal_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);


这假设C17或更高版本。make_zoned在C11/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
也可以用sys_time构造zoned_time,在这种情况下,在构造时避免了从本地的转换,并且sys_time被简单地存储。
也可以用 anotherzoned_time构造一个zoned_time。我相信这就是你要找的:

auto zoned_local_timestamp = date::zoned_time{date::current_zone(),
                                              zoned_src_timestamp};


它使用current_zone()作为time_zonezoned_src_timestamp作为“时间戳”。

  • current_zone()只是将time_zone const*返回到您计算机当前设置的本地时区。
  • zoned_src_timestamp构造时,会使用sys_time来构造新的zoned_time,因此两个zoned_time表示相同的时间点,尽管它们可能处于不同的时区,也就是说,它们具有相同的UTC时间,但本地时间不同。

然后你可以从zoned_local_timestamp中获取本地时间:

std::cout << zoned_local_timestamp.get_local_time() << " TZ\n";


zoned_time只是一个方便的 Package 器。你也可以直接使用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_timelocal_time
最后,所有这些现在都是C20的一部分。实现仍在上线。MSVC有它。gcc-14有它,在早期版本中有部分实现。LLVM有部分实现。如果你足够幸运使用C20实现,那么更喜欢date。所有内容都将在namespace std::chrono中而不是namespace date中。

相关问题