我正在使用Howard Hinnant的时区库。
https://howardhinnant.github.io/date/tz.html
我的问题:是否有可能从std::chrono::time_point构造一个date::local_time对象?
我想要做什么:
// 'tp' exists and is some std::chrono::time_point object
auto locTime = date::local_time<std::chrono::milliseconds>(tp);
this的构造函数不存在,因此会得到编译错误。我如何做到这一点(在漂亮而干净的c++ 17中)?
背景:我的最终目标是比较std::filesystem::file_time_type
和date::local_time<std::chrono::milliseconds>
。
我做
auto fileTimeTp = std::chrono::clock_cast<std::chrono::system_clock>(someDirectoryEntryObject.last_write_time());
给出了我的std::chrono::time_point作为文件日期,但这就是我卡住的地方…
答案分为两部分…
第1部分我的问题:是否有可能从
std::chrono::time_point
构造date::local_time对象?
我假设std::chrono::time_point
指向std::chrono::system_clock::time_point
(每个时钟都有自己的std::chrono::time_point
家族)。
是的,有可能。背景:system_clock::time_point
被定义为Unix时间,它与UTC非常接近。因此,要从system_clock::time_point
(在日期库/c++ 20中也称为sys_time
)到local_time
,您需要将sys_time
与time_zone
配对。这可能是您计算机当前的本地时区,或任何其他IANA时区。
获取计算机当前的本地时区:
auto tz = date::current_zone();
tz
的类型为date::time_zone const*
。time_zone
有一个名为to_local
的成员函数,可以将sys_time
转换为local_time
:
auto locTime = tz->to_local(system_clock::now());
locTime
的精度将匹配输入sys_time
的精度。
如果你想使用其他时区,那么你可以使用date::locate_zone
来获得一个date::time_zone const*
来那个时区。
auto locTime = date::locate_zone("America/New_York")->to_local(system_clock::now());
第2部分我的最终目标是比较
std::filesystem::file_time_type
和date::local_time<std::chrono::milliseconds>
。
啊,这根本不涉及local_time
。不幸的是,file_clock
没有在time_zone库中实现。
在c++ 20中,这将非常容易:给定file_time
和sys_time
,您可以使用clock_cast
将其中一个转换为另一个:
if (clock_cast<system_clock>(ftp) >= system_clock::now())
...
但是在c++ 17中它更难,而且不可移植。time_zone库使它更容易,但也不容易。
首先你必须推断出std::filesystem::file_time_type
在你的平台上的纪元。这将根据您使用的std::filesystem::file_time_type
的实现而有所不同。
现有纪元包括:
* 1970-01-01 00:00:00 UTC
* 1601-01-01 00:00:00 UTC
* 2174-01-01 00:00:00 UTC
然后减去sys_time
epoch (sys_days{1970_y/1/1}
)和file_time
epoch(例如sys_days{1601_y/1/1}
),并添加/减去该epoch以从一个测量转换到另一个。
例如:
constexpr auto diff = sys_days{1970_y/1/1} - sys_days{1601_y/1/1};
file_time_type ftp = ...
system_clock::time_point tp{ftp.time_since_epoch() - diff};
不幸的是,这是相当混乱的,我期待clock_cast
与file_clock
在c++ 20中工作。