C++ 20 chrono:如何将 time_point 与 month_day 进行比较?

问题描述

是否有一种现代而优雅的方法来确定 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)。

任何帮助将不胜感激。

解决方法

您可以通过 system_clock::now()std::chrono::sys_days 转换为 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();
}