[PATCH] libc/time/gmtime_r.c (gmtime_r): Fixed bug in calculations for dates after year 2069 or before year 1901
Freddie Chopin
freddie_chopin@op.pl
Sun Dec 7 18:34:00 GMT 2014
Hello!
It turns out that the implementation of gmtime_r() with my modifications
from September has a bug... The problem with this bug is that it shows
only for dates after 2069 or before 1901, so to actually experience this
bug time_t must be 64-bits long (or 32-bit unsigned, but I don't think
such combination exists for any platform). The root cause of the problem
is that the assumptions that there are 97 leap years in 400-year periods
and 24 leap years in 100-year periods are valid only if you consider
"full cycles". So there are 97 leap years between 2000 and 2400, or 24
leap years between 2000 and 2100, but _NOT_ between 1970 and 2070... The
fix is to move the epoch from 1st January 1970 to 1st March of 2000
(beginning of 400-year cycle, right after additional day of leap year -
29th February 2000), perform the calculations and adjust back at the end.
Attached patch implements this fix. The solution was tested by comparing
the produced value with gmtime_r() from GLIBC for every hour in
1602-year period (years 1399 - 2801, inclusive).
The idea for solution comes from implementation of the same
functionality in musl library, which used almost the same idea that I
used initially (that was a coincidence).
Unfortunatelly on ARM Cortex-M3 platform these modifications make the
function run twice as long as previously (2M iterations take 29s vs 15s
on a 16MHz clock)... I'm not really sure how is that possible (the
changes don't look that heavy), but that's the reality... As a possible
optimization, quite a lot of the code can be removed for platforms where
time_t is 32-bit long, but that's another thing.
BTW - are there any platforms which have time_t as a 64-bit variable
that use newlib, that would be affected by this problem?
Regards,
FCh
-------------- next part --------------
A non-text attachment was scrubbed...
Name: libc-time-gmtimerc-gmtimer-Fixed-bug-in-calculations.patch
Type: text/x-patch
Size: 6127 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/newlib/attachments/20141207/91a7bda7/attachment.bin>
-------------- next part --------------
2014-12-07 Freddie Chopin <freddie_chopin@op.pl>
* libc/time/gmtime_r.c (gmtime_r): Fixed bug in calculations for dates
after year 2069 or before year 1901. Ideas for solution taken from
musl's __secs_to_tm()
More information about the Newlib
mailing list