libc: fix off-by-one errors in localtime
This commit is contained in:
parent
ed58edaae9
commit
84023ed829
16
apps/test-localtime.c
Normal file
16
apps/test-localtime.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
time_t i = 1576000000;
|
||||
while (i < 2000000000) {
|
||||
struct tm * t = localtime(&i);
|
||||
|
||||
if (t->tm_sec < 0 || t->tm_sec >= 60) fprintf(stderr, "Erroneous value at %ld: sec = %d\n", i, t->tm_sec);
|
||||
if (t->tm_min < 0 || t->tm_min >= 60) fprintf(stderr, "Erroneous value at %ld: min = %d\n", i, t->tm_min);
|
||||
if (t->tm_hour < 0 || t->tm_hour >= 24) fprintf(stderr, "Erroneous value at %ld (%s) hour = %d\n", i, asctime(t), t->tm_hour);
|
||||
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -72,7 +72,7 @@ struct tm *localtime_r(const time_t *timep, struct tm * _timevalue) {
|
||||
fprintf(stderr, "adding %d...\n", added);
|
||||
long secs = added * 86400;
|
||||
|
||||
if (seconds + secs >= *timep + 1) {
|
||||
if (seconds + secs > *timep) {
|
||||
_timevalue->tm_year = year - 1900;
|
||||
year_sec = seconds;
|
||||
fprintf(stderr, "The year is %d, year_sec=%d\n", year, year_sec);
|
||||
@ -80,20 +80,20 @@ struct tm *localtime_r(const time_t *timep, struct tm * _timevalue) {
|
||||
fprintf(stderr, "Checking %d\n", month);
|
||||
secs = days_in_month(month, year) * SEC_DAY;
|
||||
fprintf(stderr, "%d vs %d\n", seconds + secs, *timep);
|
||||
if (seconds + secs >= *timep) {
|
||||
if (seconds + secs > *timep) {
|
||||
fprintf(stderr, "The month is %d.\n", month);
|
||||
_timevalue->tm_mon = month - 1;
|
||||
for (int day = 1; day <= days_in_month(month, year); ++day) {
|
||||
secs = 60 * 60 * 24;
|
||||
fprintf(stderr, "Checking day %d, %d vs . %d\n", day, seconds + secs, *timep);
|
||||
if (seconds + secs >= *timep) {
|
||||
if (seconds + secs > *timep) {
|
||||
fprintf(stderr, "The day is %d.\n", day);
|
||||
_timevalue->tm_mday = day;
|
||||
for (int hour = 1; hour <= 24; ++hour) {
|
||||
secs = 60 * 60;
|
||||
if (seconds + secs >= *timep) {
|
||||
if (seconds + secs > *timep) {
|
||||
long remaining = *timep - seconds;
|
||||
_timevalue->tm_hour = hour-1;
|
||||
_timevalue->tm_hour = hour - 1;
|
||||
_timevalue->tm_min = remaining / 60;
|
||||
_timevalue->tm_sec = remaining % 60; // can be 60 on a leap second, ignore that
|
||||
_timevalue->tm_wday = day_of_week(*timep); // oh shit
|
||||
|
Loading…
x
Reference in New Issue
Block a user