-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Consider the following program:
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <libfdatetime.h>
void test_date(double days) {
union {
double x;
uint64_t i;
} u;
u.x = days;
libfdatetime_floatingtime_t * floatingtime = NULL;
if (libfdatetime_floatingtime_initialize(&floatingtime, NULL) != 1) {
fprintf(stderr, "libfdatetime_floatingtime_initialize failed\n");
exit(EXIT_FAILURE);
}
if (libfdatetime_floatingtime_copy_from_64bit(floatingtime, u.i, NULL) != 1) {
fprintf(stderr, "libfdatetime_floatingtime_copy_from_64bit failed\n");
exit(EXIT_FAILURE);
}
uint8_t date_time_string[32];
if (libfdatetime_floatingtime_copy_to_utf8_string(floatingtime,
date_time_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME |
LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, NULL) != 1) {
fprintf(stderr, "libfdatetime_floatingtime_copy_to_utf8_string failed\n");
exit(EXIT_FAILURE);
}
printf("%f %" PRIx64 " %s\n", u.x, u.i, date_time_string);
libfdatetime_floatingtime_free(&floatingtime, NULL);
}
int main(void) {
for (int i = 0; i < 20; ++i) {
test_date(45400 + i * 1e-6);
}
return 0;
}
This generates the following output:
45400.000000 40e62b0000000000 Apr 18, 2024 00:00:00.000000000
45400.000001 40e62b00000218df Apr 18, 2024 00:00:00.086144029
45400.000002 40e62b00000431be Apr 18, 2024 00:00:00.172032058
45400.000003 40e62b0000064a9d Apr 18, 2024 00:00:00.003200087
45400.000004 40e62b000008637c Apr 18, 2024 00:00:00.089088116
45400.000005 40e62b00000a7c5b Apr 18, 2024 00:00:00.176000146
45400.000006 40e62b00000c953a Apr 18, 2024 00:00:00.006144175
45400.000007 40e62b00000eae19 Apr 18, 2024 00:00:00.092032204
45400.000008 40e62b000010c6f8 Apr 18, 2024 00:00:00.179200233
45400.000009 40e62b000012dfd7 Apr 18, 2024 00:00:00.009088007
45400.000010 40e62b000014f8b6 Apr 18, 2024 00:00:00.096000036
45400.000011 40e62b0000171194 Apr 18, 2024 00:00:00.182143181
45400.000012 40e62b0000192a73 Apr 18, 2024 00:00:01.036031210
45400.000013 40e62b00001b4352 Apr 18, 2024 00:00:01.123199239
45400.000014 40e62b00001d5c31 Apr 18, 2024 00:00:01.209087012
45400.000015 40e62b00001f7510 Apr 18, 2024 00:00:01.039231042
45400.000016 40e62b0000218def Apr 18, 2024 00:00:01.126143071
45400.000017 40e62b000023a6ce Apr 18, 2024 00:00:01.212031100
45400.000018 40e62b000025bfad Apr 18, 2024 00:00:01.043199129
45400.000019 40e62b000027d88c Apr 18, 2024 00:00:01.129087159
The first few timestamps appear to be correct (00:00:00.00, 00:00:00.086..., 00:00:00.172...,), but then in the next timestamp the fraction is actually smaller (00:00:00.003...).
A similar thing happens for the timestamps after 00:00:01 - the first few seem about right (00:00:01.036..., 00:00:01.123..., 00:00:01.209...) but then the next timestamp goes down (00:00:01.039...).
I think the issue is that the milliseconds are sometimes getting corrupted because for some reason they are being cast to uint8_t
:
libfdatetime/libfdatetime/libfdatetime_floatingtime.c
Lines 496 to 500 in 47838ce
/* There are 1000 milli seconds in a seconds correct the value to milli seconds | |
*/ | |
floatingtimestamp *= 1000.0; | |
date_time_values->milli_seconds = (uint8_t) floatingtimestamp; | |
floatingtimestamp -= date_time_values->milli_seconds; |
(Actually, even the fractional timestamps which appear to be correct may be off by a bit, because it seems that the microseconds and nanoseconds have the same issue.)