diff options
author | Steve Bennett <steveb@workware.net.au> | 2019-05-20 10:23:09 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2019-05-20 15:38:54 +1000 |
commit | 4b2b03044344f9a1b637e7258db8dfd079753f10 (patch) | |
tree | 50f0701160231dbf107ca687690b9b089f9a3c95 /jim-clock.c | |
parent | bd33d63c274c5bd13f188d961ed83e85ef0d0442 (diff) | |
download | jimtcl-4b2b03044344f9a1b637e7258db8dfd079753f10.zip jimtcl-4b2b03044344f9a1b637e7258db8dfd079753f10.tar.gz jimtcl-4b2b03044344f9a1b637e7258db8dfd079753f10.tar.bz2 |
clock scan: Implement timegm() locally
Don't rely on system timegm(), and use a locally implemented
timegm() that doesn't rely on changing TZ in the environment
Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim-clock.c')
-rw-r--r-- | jim-clock.c | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/jim-clock.c b/jim-clock.c index e489af8..cc24319 100644 --- a/jim-clock.c +++ b/jim-clock.c @@ -98,25 +98,22 @@ static int clock_cmd_format(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } #ifdef HAVE_STRPTIME -#ifndef HAVE_TIMEGM -/* Implement a basic timegm() for system's that don't have it */ -static time_t timegm(struct tm *tm) +/* Implement timegm() that doesn't require messing with timezone + * Based on: http://howardhinnant.github.io/date_algorithms.html#days_from_civil + */ +static time_t jim_timegm(const struct tm *tm) { - time_t t; - const char *tz = getenv("TZ"); - setenv("TZ", "", 1); - tzset(); - t = mktime(tm); - if (tz) { - setenv("TZ", tz, 1); - } - else { - unsetenv("TZ"); - } - tzset(); - return t; + int m = tm->tm_mon + 1; + int y = 1900 + tm->tm_year - (m <= 2); + int era = (y >= 0 ? y : y - 399) / 400; + unsigned yoe = (unsigned)(y - era * 400); + unsigned doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + tm->tm_mday - 1; + unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; + long days = (era * 146097 + (int)doe - 719468); + int secs = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; + + return days * 24 * 60 * 60 + secs; } -#endif static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -146,7 +143,7 @@ static int clock_cmd_scan(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } /* Now convert into a time_t */ - Jim_SetResultInt(interp, options.gmt ? timegm(&tm) : mktime(&tm)); + Jim_SetResultInt(interp, options.gmt ? jim_timegm(&tm) : mktime(&tm)); return JIM_OK; } |