Skip to content

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

@boimart1

Description

@boimart1

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions