scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 1ead11308a65c7fd1b816a007a597b4569b8c7f3
parent 8b7fb5985bed7f160c13007f19914317e0bcc6a6
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Tue, 14 Apr 2026 17:23:07 +0200

libc/time: Use localtime for mktime

Mktime() is specified to use local time to transform between a broken
down calendar time and a time_t.  The broken down calendar time passed
as parameter can have values out of range for the different fields, and
the function has to normalize the values before doing the calculation
based in the local time. For that reason, the field tm_isdst is important
because it marks if the time has to be calculated in dst or not, because
due to dst there are two time_t representations for the same broken down
calendar time (when the wall clock is adjusted then a date is repeated).
The standard specifies that when it is -1 then mktime() should try to
determine wheter dst is in effect for the specified time.

Commit 31198f45 had the side effect of removing any local time support
in the libc, because it removed the call to localtime() and fixed the
tm_isdst field, so mktime() only worked for UTC time, but with the
wrong effect that the tm_zone and tm_gmtoff being not set.

Diffstat:
Msrc/libc/time/mktime.c | 17+++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/libc/time/mktime.c b/src/libc/time/mktime.c @@ -93,14 +93,27 @@ normalize(struct tm *tm) tm->tm_mday = day; tm->tm_yday = yday + day - 1; tm->tm_wday = (_newyear(tm->tm_year) + tm->tm_yday) % 7; - tm->tm_isdst = 0; + return 1; } time_t mktime(struct tm *tm) { + time_t t; + struct tm *aux; + if (!normalize(tm)) return -1; - return _systime(tm); + + t = _systime(tm); + aux = localtime(&t); + + if (tm->tm_isdst == -1) + tm->tm_isdst = aux->tm_isdst; + + tm->tm_gmtoff = (tm->tm_isdst == 1) ? _tzdstoff : _tzstdoff; + t += tm->tm_gmtoff; + + return t; }