Mendes Mendes - 5 months ago 80
C++ Question

std::chrono::system_clock::now() considering the OS configured time zone

I´m programming a C++ code that is running on a BusyBox embedded linux. My code and its libraries has several calls to

to get the current time.

Since now my box was configured as dafault time zone (UTC) and everything works fine, processes running and results ok.

Now I had to set my linux to stay in a different timezone. Then I did it by configuring in the box

export TZ=UTC+3

When I issue
command and the console I get the correct time, but my calls to
I´m still getting the UTC time, not the time that is shown in the
command (the correct time).

I don´t want to change all my
calls - there are hundreds on them... And that is causing my processes to work with different time than the correct time, set on the console.

IS there any way to solve that without changing my code ? Anything I´m missing here ?

Thanks for helping.


Though unspecified by the standard, every implementation of std::chrono::system_clock::now() is tracking Unix Time, which is a very close approximation to UTC.

If you want to translate std::chrono::system_clock::now() to local time, you can either translate system_clock::time_point to time_t via system_clock::to_time_t, and then work your way through the C API (e.g. localtime), or you might try this modern timezone library which is built on top of <chrono>:

You would use this to get the current local time like this:

#include "tz.h"
#include <iostream>

    using namespace date;
    using namespace std::chrono;
    auto t = make_zoned(current_zone(), system_clock::now());
    std::cout << t << '\n';

make_zoned is a factory function which returns the type zoned_time with whatever precision your system_clock supports (e.g. nanoseconds). It is a pairing of a time_zone and a system_clock::time_point.

You can get a local_time<Duration> which is a std::chrono::time_point like this:

    auto t = make_zoned(current_zone(), system_clock::now());
    auto lt = t.get_local_time();
    std::cout << lt.time_since_epoch().count() << '\n';

Though the library has a remote API to download the IANA timezone database automatically, that API can be disabled by compiling with -DHAS_REMOTE_API=0. This is all detailed in the installation instructions. With the remote API disabled, you would have to manually download the database from IANA timezone database (it's just a tar.gz).