Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

local_microsec_clock::local_time(time_zone_ptr) occasionally returns an incorrect time #233

Open
boimart1 opened this issue Aug 21, 2023 · 0 comments · May be fixed by #234
Open

local_microsec_clock::local_time(time_zone_ptr) occasionally returns an incorrect time #233

boimart1 opened this issue Aug 21, 2023 · 0 comments · May be fixed by #234

Comments

@boimart1
Copy link

boimart1 commented Aug 21, 2023

Extremely rarely, a call to local_microsec_clock::local_time(time_zone_ptr) will return a result about 1 second in the past.

On my local machine, running the following code:

#include <boost/date_time/local_time/local_time.hpp>
#include <iostream>

int main() {
    boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("EST-5"));

    for (int i = 0; i < 100'000'000; ++i)
    {
        boost::local_time::local_date_time t0 = boost::local_time::local_microsec_clock::local_time(zone);
        boost::local_time::local_date_time t1 = boost::local_time::local_microsec_clock::local_time(zone);
        if (t1 < t0)
        {
            std::cout << i << ": time went from " << t0 << " to " << t1 << '\n';
        }
    }

    return 0;
}

produces ~10-15 incorrect results for 100M calls, or one incorrect result per ~7-10M calls.

The output suggests that this always occurs when the second ticks. The fractional part rolls over, but the seconds do not change.

81899680: time went from 2023-Aug-21 09:17:12.999739 EST to 2023-Aug-21 09:17:12.000740 EST
91444271: time went from 2023-Aug-21 09:17:27.999755 EST to 2023-Aug-21 09:17:27.000752 EST
92719444: time went from 2023-Aug-21 09:17:29.999467 EST to 2023-Aug-21 09:17:29.000465 EST

It looks like the issue is caused by the second ticking between the calls to second_clock::universal_time() and second_clock::local_time(), which causes utc_offset to be off by 1 second.

// we'll need to know the utc_offset this machine has
// in order to get a utc_time_type set to utc
utc_time_type utc_time = second_clock::universal_time();
time_duration_type utc_offset = second_clock::local_time() - utc_time;
// use micro clock to get a local time with sub seconds
// and adjust it to get a true utc time reading with sub seconds
utc_time = microsec_clock<utc_time_type>::local_time() - utc_offset;
return time_type(utc_time, tz_ptr);

I intend to submit a PR with a solution soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant