scc

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

commit c715d4030343260c37b064df864a91ec1064a13b
parent 999d029a5b062ef4ceb1e7e145eaa1c41e4bfcc5
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Sun, 19 Apr 2026 20:55:58 +0200

libc/time: Support negative time values

Diffstat:
Msrc/libc/time/gmtime.c | 50++++++++++++++++++++++++++++++++++----------------
Msrc/libc/time/mktime.c | 12++++++++++--
2 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/src/libc/time/gmtime.c b/src/libc/time/gmtime.c @@ -1,3 +1,4 @@ +#include <stdlib.h> #include <time.h> #include "../libc.h" @@ -7,28 +8,45 @@ struct tm * gmtime(const time_t *tim) { + div_t d; + int month, year; + time_t tday, day, t = *tim; static struct tm tm; - time_t day; - int i; - tm.tm_sec = *tim % SECDAY; - tm.tm_min = tm.tm_sec / 60; - tm.tm_sec %= 60; - tm.tm_hour = tm.tm_min / 60; - tm.tm_min %= 60; - day = *tim / SECDAY; + day = t / SECDAY; + tday = t % SECDAY; + if (tday < 0) { + tday += SECDAY; + day--; + } - tm.tm_wday = (day + THU) % 7; /* 1/1/1970 was Thursday */ + d = div(tday, 60); + tm.tm_sec = d.rem; - for (i = EPOCH; day >= _daysyear(i); ++i) - day -= _daysyear(i); - tm.tm_year = i - 1900; + d = div(d.quot, 60); + tm.tm_min = d.rem; + + tm.tm_hour = d.quot; + + /* 1/1/1970 was Thursday */ + tm.tm_wday = (day + THU) % 7; + + year = EPOCH; + if (day >= 0) { + while (day >= _daysyear(year)) + day -= _daysyear(year++); + } else { + while (day < 0) + day += _daysyear(--year); + } + + tm.tm_year = year - 1900; tm.tm_yday = day; - _daysmon[FEB] = FEBDAYS(i); - for (i = JAN; day >= _daysmon[i]; i++) - day -= _daysmon[i]; - tm.tm_mon = i; + _daysmon[FEB] = FEBDAYS(year); + for (month = JAN; day >= _daysmon[month]; month++) + day -= _daysmon[month]; + tm.tm_mon = month; tm.tm_mday = day + 1; tm.tm_isdst = 0; diff --git a/src/libc/time/mktime.c b/src/libc/time/mktime.c @@ -110,8 +110,15 @@ mktime(struct tm *tm) t = 0; year = tm->tm_year + BASEYEAR; - for (i = EPOCH; i < year; ++i) - t += _daysyear(i) * SECDAY; + + if (year >= EPOCH) { + for (i = EPOCH; i < year; ++i) + t += _daysyear(i) * SECDAY; + } else { + for (i = EPOCH; i > year; --i) + t -= _daysyear(i) * SECDAY; + } + for (i = 0; i < tm->tm_mon; ++i) t += _daysmon[i] * SECDAY; @@ -119,6 +126,7 @@ mktime(struct tm *tm) t += tm->tm_min * SECMIN; t += tm->tm_hour * SECHOUR; t += (tm->tm_mday-1) * SECDAY; + aux = localtime(&t); if (tm->tm_isdst == -1)