2
\$\begingroup\$

I came up with the following function to obtain epoch seconds that correspond to previous midnight in a local time zone:

#include <iostream>
#include <chrono>
#include <date/date.h>
#include <date/tz.h>

long local_midnight_epoch() {
    using namespace date;
    using namespace std::chrono;
    auto t = std::chrono::system_clock::now();
    auto* zone = date::current_zone();
    auto zt = make_zoned(zone, t);
    zt = floor<days>(zt.get_local_time());
    auto seconds_since_midnight = floor<seconds>(t - zt.get_sys_time());
    std::chrono::time_point<std::chrono::system_clock> ts = std::chrono::system_clock::now();
    auto epoch = std::chrono::duration_cast<std::chrono::seconds>(ts.time_since_epoch());
    epoch -= seconds_since_midnight;
    return epoch.count();
}

int main(void) {
    std::cerr << local_midnight_epoch() << std::endl;
}

The code uses Howard Hinnant's date library. It first computes seconds passed since midnight in a local time zone, and then subtract that the current epoch. Is there an easier way to accomplish this? Thanks.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

This is a good attempt at getting the UTC timestamp associated with the previous local midnight. For me it gets within a second or two of the correct answer.

Here's what I recommend, with each line commented with what it does:

long local_midnight_epoch2() {
    using namespace date;
    using namespace std::chrono;
    // current time in seconds, UTC
    auto now = floor<seconds>(system_clock::now());
    // corresponding local time
    zoned_seconds zt{current_zone(), now};
    // reset to previous local midnight
    zt = floor<days>(zt.get_local_time());
    // get UTC corresponding to local midnight
    auto epoch = zt.get_sys_time();
    return epoch.time_since_epoch().count();
}

The biggest advantage over what you have is that it only calls system_clock::now() once. Otherwise it is quite similar to what you have.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.