Bug in datetime::timeval_to_datetime()

Dec 10, 2014 at 8:48 AM
In utilities/asyncrt_utils.cpp:
#ifndef WIN32
 datetime datetime::timeval_to_datetime(struct timeval time)
 {
     const uint64_t epoch_offset = 11644473600LL; // diff between windows and unix epochs (seconds)
     uint64_t result = epoch_offset + time.tv_sec;
     result *= _secondTicks; // convert to 10e-7
     result += time.tv_usec; //add microseconds (in 10e-7)
     return datetime(result);
 }
 #endif
The timeval.tv_usec field is units of microseconds, i.e. 10e-6 seconds. I know that datetime is in units of 100ns (i.e. 10e-7 seconds). I'm pretty sure you need to multiply time.tv_usec by 10 before adding it to result.

Jason
Coordinator
Dec 11, 2014 at 4:16 AM
Hi Jason,

Yes you are correct about this code it incorrectly is preforming the conversion in this private function. There are two uses of this helper function in our code base. First is with the from_string(...) function which in a very sneaky way stores a value in 10e-7 in the tv_usec field. The second is the utc_now() function, which obviously hits the conversion problem you point out. So the problem only actually happens if you call utc_now().

I have a fix that will be checked in shortly that fixes this up.

Thanks for reporting the issue.
Steve
Marked as answer by jdzions on 12/11/2014 at 3:16 PM
Dec 11, 2014 at 5:27 AM
I built a class just like this not long ago; I suspect your "sneaky thing" is the same one I did in my operator<<() method (left-pad tv_usec with 0's to six characters wide, then emit a hardcoded 0 after that).

Sent from my Windows Phone

Coordinator
Dec 16, 2014 at 1:32 AM
Basically someone store a 10e-7 value in a field that is clearly documented to use 10e-6.

Regardless this has been fixed in the development branch and will be in the next release 2.4.0. Thanks again for reporting the issue.

Steve