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.
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();
}