Search code examples
c++datec++-chrono

How can I get the day of the week using std::chrono after having calculated the day/month/year?


I've calculated the day, day of month and year, and seconds, minutes, and hours using std::chrono::local_days, I just now need to get the day of the week. The code I'm using was given by Howard Hinnant on an answer here, comments are mine:

auto tp = std::chrono::system_clock::now();
static auto const tz = std::chrono::current_zone();
static auto info = tz->get_info(tp); // CACHE THE TIMEZONE INFO
if (tp >= info.end) // APPARENTLY THE TIME ZONE INFO CAN CHANGE UP TO TWICE A YEAR
    info = tz->get_info(tp);
auto tpl = std::chrono::local_days{} + (tp + info.offset - std::chrono::sys_days{});
auto tpd = floor<std::chrono::days>(tpl);
std::chrono::year_month_day ymd{ tpd };
std::chrono::hh_mm_ss hms{ tpl - tpd };

At this point I have the what I mentioned above, how can I get the day of the week with as few redundant calls as possible?


Solution

  • The other answers get the correct answer, but here is the most efficient method:

    std::chrono::weekday wd{tpd};
    

    Just convert your local_days to weekday. This will get you the local weekday (because you converted from local_days).

    All this conversion does is execute this low-level algorithm:

    return static_cast<unsigned>(tpd >= -4 ? (tpd +4) % 7 : (tpd +5) % 7 + 6);
    

    so it is about as efficient as you can get.


    Other comments:

    // APPARENTLY THE TIME ZONE INFO CAN CHANGE UP TO TWICE A YEAR

    Actually more. There is no limit to the craziness of politicians.

    Here is a simpler way to get the local time (tpl):

    auto tpl = tz->to_local(tp);
    

    I don't recommend going thru the sys_info unless you are doing thousands of such conversions and need the very ultimate in performance. Certainly for just starting out, just let the time_zone do the conversion for you.