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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions