Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ 20 chrono: How to compare time_point with month_day?

Is there a modern and elegant way to determine if the month and day in a time_point variable match a given month_day variable?

For example, I want to know if today is Christmas. I have the following code:

#include <chrono>

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

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

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

Modern and elegant: I mean if possible, I would prefer not to use old C types (something like std::time_t and std::tm) and string comparisons (something like std::put_time).

Any help would be appreciated.

like image 251
Sprite Avatar asked Jun 01 '21 01:06

Sprite


People also ask

What is std :: Chrono :: Time_point?

Class template std::chrono::time_point represents a point in time. It is implemented as if it stores a value of type Duration indicating the time interval from the start of the Clock 's epoch. Clock must meet the requirements for Clock or be std::chrono::local_t (since C++20).

What is Chrono C++?

Chrono in C++ chrono is the name of a header and also of a sub-namespace: All the elements in this header (except for the common_type specializations) are not defined directly under the std namespace (like most of the standard library) but under the std::chrono namespace.


1 Answers

You can convert system_clock::now() to a std::chrono::year_month_day type via a std::chrono::sys_days. In practice this might look something like

#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;
}

As Howard Hinnant pointed out, this will determine Christmas in UTC. You're more likely to be after Christmas in the local time zone: to do so, we must first transform Now into our local time zone: (Note std::chrono::current_zone is not yet provided by libstdc++ or libc++, as far as I can tell.)

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();
}
like image 178
N. Shead Avatar answered Oct 13 '22 18:10

N. Shead