/* * Copyright 2001-2004 Brandon Long * All Rights Reserved. * * ClearSilver Templating System * * This code is made available under the terms of the ClearSilver License. * http://www.clearsilver.net/license.hdf * */ #include "cs_config.h" #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <limits.h> #include "util/neo_misc.h" #include "neo_date.h" /* This is pretty much a HACK. Eventually, we might bring the parsing * and stuff into this library (we can use the public domain source code * from ftp://elsie.nci.nih.gov/pub/ as a base) * * For now, we just do a putenv(TZ)... which sucks, especially since * many versions of putenv do a strdup... and then leak the memory the * next time you putenv the same var. */ /* Since this is set to a partial filename and TZ=, it can't be bigger * than this */ static char TzBuf[_POSIX_PATH_MAX + 4]; static int time_set_tz (const char *mytimezone) { snprintf (TzBuf, sizeof(TzBuf), "TZ=%s", mytimezone); putenv(TzBuf); tzset(); return 0; } void neo_time_expand (const time_t tt, const char *mytimezone, struct tm *ttm) { const char *cur_tz = getenv("TZ"); int change_back = 0; if (cur_tz == NULL || strcmp(mytimezone, cur_tz)) { time_set_tz (mytimezone); change_back = 1; } localtime_r (&tt, ttm); if (cur_tz && change_back) { time_set_tz(cur_tz); } } time_t neo_time_compact (struct tm *ttm, const char *mytimezone) { time_t r; int save_isdst = ttm->tm_isdst; const char *cur_tz = getenv("TZ"); int change_back = 0; if (cur_tz == NULL || strcmp(mytimezone, cur_tz)) { time_set_tz (mytimezone); change_back = 1; } ttm->tm_isdst = -1; r = mktime(ttm); ttm->tm_isdst = save_isdst; if (cur_tz && change_back) { time_set_tz(cur_tz); } return r; } /* Hefted from NCSA HTTPd src/util.c -- What a pain in the ass. */ long neo_tz_offset(struct tm *ttm) { /* We assume here that HAVE_TM_ZONE implies HAVE_TM_GMTOFF and * HAVE_TZNAME implies HAVE_TIMEZONE since AC_STRUCT_TIMEZONE defines * the former and not the latter */ #if defined(HAVE_TM_ZONE) return ttm->tm_gmtoff; #elif defined(HAVE_TZNAME) long tz; #ifndef __CYGWIN__ tz = - timezone; #else tz = - _timezone; #endif if(ttm->tm_isdst) tz += 3600; return tz; #else long tz; struct tm loc_tm, gmt_tm; time_t tt; /* We probably shouldn't use the _r versions here since this * is for older platforms... */ tt = time(NULL); localtime_r(&tt, &loc_tm); gmtime_r(&tt, &gmt_tm); tz = mktime(&loc_tm) - mktime(&gmt_tm); return tz; #endif /* GMT OFFSet Crap */ }