1 /*
2 * Copyright 2001-2004 Brandon Long
3 * All Rights Reserved.
4 *
5 * ClearSilver Templating System
6 *
7 * This code is made available under the terms of the ClearSilver License.
8 * http://www.clearsilver.net/license.hdf
9 *
10 */
11
12 #include "cs_config.h"
13
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <time.h>
18 #include <limits.h>
19 #include "util/neo_misc.h"
20 #include "neo_date.h"
21
22 /* This is pretty much a HACK. Eventually, we might bring the parsing
23 * and stuff into this library (we can use the public domain source code
24 * from ftp://elsie.nci.nih.gov/pub/ as a base)
25 *
26 * For now, we just do a putenv(TZ)... which sucks, especially since
27 * many versions of putenv do a strdup... and then leak the memory the
28 * next time you putenv the same var.
29 */
30
31 /* Since this is set to a partial filename and TZ=, it can't be bigger
32 * than this */
33 static char TzBuf[_POSIX_PATH_MAX + 4];
34
time_set_tz(const char * mytimezone)35 static int time_set_tz (const char *mytimezone)
36 {
37 snprintf (TzBuf, sizeof(TzBuf), "TZ=%s", mytimezone);
38 putenv(TzBuf);
39 tzset();
40 return 0;
41 }
42
neo_time_expand(const time_t tt,const char * mytimezone,struct tm * ttm)43 void neo_time_expand (const time_t tt, const char *mytimezone, struct tm *ttm)
44 {
45 const char *cur_tz = getenv("TZ");
46 int change_back = 0;
47 if (cur_tz == NULL || strcmp(mytimezone, cur_tz)) {
48 time_set_tz (mytimezone);
49 change_back = 1;
50 }
51 localtime_r (&tt, ttm);
52 if (cur_tz && change_back) {
53 time_set_tz(cur_tz);
54 }
55 }
56
neo_time_compact(struct tm * ttm,const char * mytimezone)57 time_t neo_time_compact (struct tm *ttm, const char *mytimezone)
58 {
59 time_t r;
60 int save_isdst = ttm->tm_isdst;
61
62 const char *cur_tz = getenv("TZ");
63 int change_back = 0;
64 if (cur_tz == NULL || strcmp(mytimezone, cur_tz)) {
65 time_set_tz (mytimezone);
66 change_back = 1;
67 }
68 ttm->tm_isdst = -1;
69 r = mktime(ttm);
70 ttm->tm_isdst = save_isdst;
71 if (cur_tz && change_back) {
72 time_set_tz(cur_tz);
73 }
74 return r;
75 }
76
77 /* Hefted from NCSA HTTPd src/util.c -- What a pain in the ass. */
neo_tz_offset(struct tm * ttm)78 long neo_tz_offset(struct tm *ttm) {
79 /* We assume here that HAVE_TM_ZONE implies HAVE_TM_GMTOFF and
80 * HAVE_TZNAME implies HAVE_TIMEZONE since AC_STRUCT_TIMEZONE defines
81 * the former and not the latter */
82 #if defined(HAVE_TM_ZONE)
83 return ttm->tm_gmtoff;
84 #elif defined(HAVE_TZNAME)
85 long tz;
86 #ifndef __CYGWIN__
87 tz = - timezone;
88 #else
89 tz = - _timezone;
90 #endif
91 if(ttm->tm_isdst)
92 tz += 3600;
93 return tz;
94 #else
95 long tz;
96 struct tm loc_tm, gmt_tm;
97 time_t tt;
98
99 /* We probably shouldn't use the _r versions here since this
100 * is for older platforms... */
101 tt = time(NULL);
102 localtime_r(&tt, &loc_tm);
103 gmtime_r(&tt, &gmt_tm);
104
105 tz = mktime(&loc_tm) - mktime(&gmt_tm);
106 return tz;
107 #endif /* GMT OFFSet Crap */
108 }
109
110