【问题标题】:How to generate date::local_time from std::chrono_time_point如何从 std::chrono_time_point 生成 date::local_time
【发布时间】:2021-10-23 19:13:33
【问题描述】:

我正在使用 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&lt;std::chrono::milliseconds&gt; 进行比较。

我愿意

auto fileTimeTp = std::chrono::clock_cast&lt;std::chrono::system_clock&gt;(someDirectoryEntryObject.last_write_time());

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

【问题讨论】:

    标签: c++ date chrono


    【解决方案1】:

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

    第 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 Time,与 UTC 非常接近。所以要从system_clock::time_point(在日期库/C++20 中也称为sys_time)到local_time,您需要将sys_timetime_zone 配对。这可能是您计算机的当前本地时区,或任何其他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 部分

    我的最终目标是将std::filesystem::file_time_typedate::local_time&lt;std::chrono::milliseconds&gt; 进行比较。

    啊,这根本不会涉及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}),然后加/减那个纪元以从一种度量转换为另一种度量。

    例如:

    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 一起工作。

    【讨论】:

    • 谢谢!我认为您的意思是 auto locTime = tz-&gt;to_local(system_clock::now()); 而不是 auto locTime = tz-&gt;local_time(system_clock::now()); 但它是这样工作的。
    猜你喜欢
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多