【问题标题】:C++ 20 chrono: How to compare time_point with month_day?C++ 20 chrono:如何比较 time_point 和 month_day?
【发布时间】:2021-08-19 05:34:21
【问题描述】:

是否有一种现代而优雅的方法来确定 time_point 变量中的 monthday 是否与给定的 month_day 变量匹配?

例如,我想知道今天是不是圣诞节。我有以下代码:

#include <chrono>

bool IsTodayChristmas()
{
    using namespace std::chrono;

    constexpr month_day Christmas = {December / 25};
    auto Now = system_clock::now();

    // return Now == Christmas; // How to?
}

现代而优雅:我的意思是,如果可能的话,我宁愿不使用旧的 C 类型(例如 std::time_tstd::tm)和字符串比较(例如 std::put_time)。

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ date c++20 chrono


    【解决方案1】:

    您可以通过std::chrono::sys_dayssystem_clock::now() 转换为std::chrono::year_month_day 类型。在实践中,这可能看起来像

    #include <chrono>
    
    bool IsTodayChristmas() {
        using namespace std::chrono;
    
        constexpr month_day Christmas = {December / 25};
        auto Now = year_month_day{floor<days>(system_clock::now())};
    
        // either
        return Now == Christmas / Now.year();
        // or
        return Now.month() / Now.day() == Christmas;
    }
    

    正如 Howard Hinnant 所指出的,这将决定 UTC 的圣诞节。您更有可能在本地时区的圣诞节之后:为此,我们必须首先将 Now 转换为我们的本地时区:(注意 std::chrono::current_zone 尚未由 libstdc++ 或 libc++ 提供,据我所知能看出来。)

    bool IsTodayChristmas() {
        using namespace std::chrono;
    
        constexpr month_day Christmas = {December / 25};
        auto Now_local = current_zone()->to_local(system_clock::now());
        auto Today = year_month_day{floor<days>(Now_local)};
    
        return Today == Christmas / Today.year();
    }
    

    【讨论】:

    • 好答案。但这决定了UTC是否是圣诞节。在当地时区还是在澳大利亚/悉尼呢?
    • @HowardHinnant 啊,这是一个好点;我假设您会通过local_days,尽管我对此并不完全有信心。如果您回答,我会指出这一点!
    • 我支持你! :-)
    • 赞成。 :-) 不错的工作。是的,直接使用time_zone current_zone() 是一个很好的方法。但是使用zoned_time 也是一个好方法。 zoned_time 本质上是一个比直接使用time_zone 更高级的便利API。但在这种情况下并没有买那么多的便利(也不会花很多钱)。无论哪种方式,获取当前本地时间并将其精确到天是获取当前本地日期并将其与圣诞节进行比较的正确方法。
    • 如果您需要知道在当地时间或 UTC 以外的某个地方是否是圣诞节,则将 auto Now_local = current_zone()-&gt;to_local(system_clock::now()); 更改为 auto Now_local = locate_zone("Australia/Sydney")-&gt;to_local(system_clock::now());,其他一切都可以保持不变。在与时间打交道时,正确回答问题往往比正确回答更难。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多