如何从 std::chrono_time_point 生成 date::local_time

How to generate date::local_time from std::chrono_time_point

我正在使用 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);

此构造函数不存在,因此出现编译错误。 我该怎么做(在漂亮干净的 C++17 中)?

背景: 我的最终目标是比较 std::filesystem::file_time_typedate::local_time<std::chrono::milliseconds>.

我愿意

auto fileTimeTp = std::chrono::clock_cast<std::chrono::system_clock>(someDirectoryEntryObject.last_write_time());

这给出了我的 std::chrono::time_point 作为文件日期,但这就是我卡住的地方...

这是一个分为两部分的答案...

第 1 部分

My question: Is it possible to construct a date::local_time object from a std::chrono::time_point?

我假设 std::chrono::time_point 指的是 std::chrono::system_clock::time_point(每个时钟都有自己的 std::chrono::time_point 系列)。

是的,这是可能的。背景:system_clock::time_point 定义为 Unix Time which is a close approximation to UTC. So to go from system_clock::time_point (also know as sys_time in the date library / C++20) to local_time, you need to pair the sys_time with a time_zone. This could be your computer's current local time zone, or any other IANA time zone.

获取计算机的当前本地时区:

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")->local_time(system_clock::now());

第 2 部分

My ultimate goal is to compare a std::filesystem::file_time_type to a date::local_time<std::chrono::milliseconds>.

啊,这根本不涉及local_time。不幸的是,file_clock 未在 the time_zone library 中实现。

在 C++20 中,这将非常简单:给定一个 file_time 和一个 sys_time,您可以使用 clock_cast:

将其中一个转换为另一个
if (clock_cast<system_clock>(ftp) >= system_clock::now())
    ...

但是在 C++17 中它更难,而且不可移植。 the time_zone library 使它更容易,但并不容易。

你首先要在你的平台上推导出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 纪元 (sys_days{1970_y/1/1}) 和 file_time 纪元(例如 sys_days{1601_y/1/1}),然后 add/subtract 要转换的纪元一个衡量标准。

例如:

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 在 C++20 中使用 file_clock