Reputation: 593
boost version 1.71.0, OS Ubuntu 20
#include <iostream>
#include <boost/date_time/c_local_time_adjustor.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <thread>
int main(int argc, char const* argv[])
{
while (true)
{
auto utc_now = boost::date_time::second_clock<boost::posix_time::ptime>::universal_time();
auto now = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(utc_now);
std::cout << "now: " << to_simple_string(now) << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(10));
}
return 0;
}
After running this code, I change the time zone using timedatectl
and these changes are not displayed in the program until I restart it:
./program
now: 2024-Mar-12 12:30:09
# in another terminal change the timezone: sudo timedatectl set-timezone <some new timezone>
now: 2024-Mar-12 12:30:19 # the same local time, was not updated
And if you run the program again, the local time is updated:
./program
now: 2024-Mar-12 06:30:25 # new local time
How to make the local time updated while the program is running?
Upvotes: 0
Views: 96
Reputation: 451
By looking at the source code of boost::datetime, utc_to_local() calls an internal function called localtime(), which in turns call the POSIX function localtime_r().
As specified on the manpage in the notes sections,
According to POSIX.1-2004, localtime() is required to behave as though tzset(3) was called, while localtime_r() does not have this requirement. For portable code tzset(3) should be called before localtime_r().
In conclusion, the glibc library function localtime_r()
does not behave as one would expect, you need to call tzset()
everytime to retrieve expected result when the timezone has been changed. Boost library does not (for optimization purpose perhaps), hence you must call it yourself, and wrap it inside #ifdefs if you intend to write portable code.
I do not know if the behavior of the boost function (i.e. not taking into account timezone changes) is a bug or a "feature".
Upvotes: 1