From 9505b4285989cd81d78ff76fc76d4f3c8d937741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= Date: Fri, 8 Dec 2023 10:20:28 +0100 Subject: [PATCH] EFUNs [AIX,NT]: Improved support for time beyond 2038-01-19 in mktime(). Fixes calculation for dates past 2038-01-19T03:14:07 UTC. The issue was caused by the C division operator rounding negative values toward zero rather than toward negative infinity. Now the dividend should stay positive to avoid surprises. Note that mktime() is best-effort for timezone offsets other than 0. --- src/builtin_functions.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 92f436a402..8770f666d7 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5994,11 +5994,17 @@ time_t mktime_zone(struct tm *date, int other_timezone, int tz) * The calendar repeats every 28 years, so offset it appropriately. * Offset years before 1971 in order to avoid issues near 1970-01-01. */ - if ((date->tm_year <= -300) || (date->tm_year > 130)) { + if (date->tm_year <= -300) { int y = (100 - date->tm_year)/400; date->tm_year += y * 400; ydelta += y * 400; retval -= y * 12622780800LL; /* 400 years in seconds. */ + } else if (date->tm_year > 130) { + /* NB: Duplicate of the above due to rounding to zero. */ + int y = (date->tm_year + 300)/400; + date->tm_year -= y * 400; + ydelta -= y * 400; + retval += y * 12622780800LL; /* 400 years in seconds. */ } if (date->tm_year <= -30) { /* Before 1870. */ int y = -date->tm_year/100;