1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2015 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Derick Rethans <derick@derickrethans.nl> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #include "timelib.h"
22 #include <ctype.h>
23 #include <math.h>
24
25 #define TIMELIB_TIME_FREE(m) \
26 if (m) { \
27 free(m); \
28 m = NULL; \
29 } \
30
31 #define TIMELIB_LLABS(y) (y < 0 ? (y * -1) : y)
32
33 #define HOUR(a) (int)(a * 60)
34
timelib_time_ctor(void)35 timelib_time* timelib_time_ctor(void)
36 {
37 timelib_time *t;
38 t = calloc(1, sizeof(timelib_time));
39
40 return t;
41 }
42
timelib_rel_time_ctor(void)43 timelib_rel_time* timelib_rel_time_ctor(void)
44 {
45 timelib_rel_time *t;
46 t = calloc(1, sizeof(timelib_rel_time));
47
48 return t;
49 }
50
timelib_time_clone(timelib_time * orig)51 timelib_time* timelib_time_clone(timelib_time *orig)
52 {
53 timelib_time *tmp = timelib_time_ctor();
54 memcpy(tmp, orig, sizeof(timelib_time));
55 if (orig->tz_abbr) {
56 tmp->tz_abbr = strdup(orig->tz_abbr);
57 }
58 if (orig->tz_info) {
59 tmp->tz_info = orig->tz_info;
60 }
61 return tmp;
62 }
63
timelib_rel_time_clone(timelib_rel_time * rel)64 timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *rel)
65 {
66 timelib_rel_time *tmp = timelib_rel_time_ctor();
67 memcpy(tmp, rel, sizeof(timelib_rel_time));
68 return tmp;
69 }
70
timelib_time_tz_abbr_update(timelib_time * tm,char * tz_abbr)71 void timelib_time_tz_abbr_update(timelib_time* tm, char* tz_abbr)
72 {
73 unsigned int i;
74
75 TIMELIB_TIME_FREE(tm->tz_abbr);
76 tm->tz_abbr = strdup(tz_abbr);
77 for (i = 0; i < strlen(tz_abbr); i++) {
78 tm->tz_abbr[i] = toupper(tz_abbr[i]);
79 }
80 }
81
timelib_time_dtor(timelib_time * t)82 void timelib_time_dtor(timelib_time* t)
83 {
84 TIMELIB_TIME_FREE(t->tz_abbr);
85 TIMELIB_TIME_FREE(t);
86 }
87
timelib_rel_time_dtor(timelib_rel_time * t)88 void timelib_rel_time_dtor(timelib_rel_time* t)
89 {
90 TIMELIB_TIME_FREE(t);
91 }
92
timelib_time_offset_ctor(void)93 timelib_time_offset* timelib_time_offset_ctor(void)
94 {
95 timelib_time_offset *t;
96 t = calloc(1, sizeof(timelib_time_offset));
97
98 return t;
99 }
100
timelib_time_offset_dtor(timelib_time_offset * t)101 void timelib_time_offset_dtor(timelib_time_offset* t)
102 {
103 TIMELIB_TIME_FREE(t->abbr);
104 TIMELIB_TIME_FREE(t);
105 }
106
timelib_tzinfo_ctor(char * name)107 timelib_tzinfo* timelib_tzinfo_ctor(char *name)
108 {
109 timelib_tzinfo *t;
110 t = calloc(1, sizeof(timelib_tzinfo));
111 t->name = strdup(name);
112
113 return t;
114 }
115
timelib_tzinfo_clone(timelib_tzinfo * tz)116 timelib_tzinfo *timelib_tzinfo_clone(timelib_tzinfo *tz)
117 {
118 timelib_tzinfo *tmp = timelib_tzinfo_ctor(tz->name);
119 tmp->bit32.ttisgmtcnt = tz->bit32.ttisgmtcnt;
120 tmp->bit32.ttisstdcnt = tz->bit32.ttisstdcnt;
121 tmp->bit32.leapcnt = tz->bit32.leapcnt;
122 tmp->bit32.timecnt = tz->bit32.timecnt;
123 tmp->bit32.typecnt = tz->bit32.typecnt;
124 tmp->bit32.charcnt = tz->bit32.charcnt;
125
126 tmp->trans = (int32_t *) malloc(tz->bit32.timecnt * sizeof(int32_t));
127 tmp->trans_idx = (unsigned char*) malloc(tz->bit32.timecnt * sizeof(unsigned char));
128 memcpy(tmp->trans, tz->trans, tz->bit32.timecnt * sizeof(int32_t));
129 memcpy(tmp->trans_idx, tz->trans_idx, tz->bit32.timecnt * sizeof(unsigned char));
130
131 tmp->type = (ttinfo*) malloc(tz->bit32.typecnt * sizeof(struct ttinfo));
132 memcpy(tmp->type, tz->type, tz->bit32.typecnt * sizeof(struct ttinfo));
133
134 tmp->timezone_abbr = (char*) malloc(tz->bit32.charcnt);
135 memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->bit32.charcnt);
136
137 tmp->leap_times = (tlinfo*) malloc(tz->bit32.leapcnt * sizeof(tlinfo));
138 memcpy(tmp->leap_times, tz->leap_times, tz->bit32.leapcnt * sizeof(tlinfo));
139
140 return tmp;
141 }
142
timelib_tzinfo_dtor(timelib_tzinfo * tz)143 void timelib_tzinfo_dtor(timelib_tzinfo *tz)
144 {
145 TIMELIB_TIME_FREE(tz->name);
146 TIMELIB_TIME_FREE(tz->trans);
147 TIMELIB_TIME_FREE(tz->trans_idx);
148 TIMELIB_TIME_FREE(tz->type);
149 TIMELIB_TIME_FREE(tz->timezone_abbr);
150 TIMELIB_TIME_FREE(tz->leap_times);
151 TIMELIB_TIME_FREE(tz->location.comments);
152 TIMELIB_TIME_FREE(tz);
153 tz = NULL;
154 }
155
timelib_get_tz_abbr_ptr(timelib_time * t)156 char *timelib_get_tz_abbr_ptr(timelib_time *t)
157 {
158 if (!t->sse_uptodate) {
159 timelib_update_ts(t, NULL);
160 };
161 return t->tz_abbr;
162 }
163
timelib_error_container_dtor(timelib_error_container * errors)164 void timelib_error_container_dtor(timelib_error_container *errors)
165 {
166 int i;
167
168 for (i = 0; i < errors->warning_count; i++) {
169 free(errors->warning_messages[i].message);
170 }
171 free(errors->warning_messages);
172 for (i = 0; i < errors->error_count; i++) {
173 free(errors->error_messages[i].message);
174 }
175 free(errors->error_messages);
176 free(errors);
177 }
178
timelib_date_to_int(timelib_time * d,int * error)179 signed long timelib_date_to_int(timelib_time *d, int *error)
180 {
181 timelib_sll ts;
182
183 ts = d->sse;
184
185 if (ts < LONG_MIN || ts > LONG_MAX) {
186 if (error) {
187 *error = 1;
188 }
189 return 0;
190 }
191 if (error) {
192 *error = 0;
193 }
194 return (signed long) d->sse;
195 }
196
timelib_decimal_hour_to_hms(double h,int * hour,int * min,int * sec)197 void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec)
198 {
199 *hour = floor(h);
200 *min = floor((h - *hour) * 60);
201 *sec = (h - *hour - ((float) *min / 60)) * 3600;
202 }
203
timelib_dump_date(timelib_time * d,int options)204 void timelib_dump_date(timelib_time *d, int options)
205 {
206 if ((options & 2) == 2) {
207 printf("TYPE: %d ", d->zone_type);
208 }
209 printf("TS: %lld | %s%04lld-%02lld-%02lld %02lld:%02lld:%02lld",
210 d->sse, d->y < 0 ? "-" : "", TIMELIB_LLABS(d->y), d->m, d->d, d->h, d->i, d->s);
211 if (d->f > +0.0) {
212 printf(" %.5f", d->f);
213 }
214
215 if (d->is_localtime) {
216 switch (d->zone_type) {
217 case TIMELIB_ZONETYPE_OFFSET: /* Only offset */
218 printf(" GMT %05d%s", d->z, d->dst == 1 ? " (DST)" : "");
219 break;
220 case TIMELIB_ZONETYPE_ID: /* Timezone struct */
221 /* Show abbreviation if wanted */
222 if (d->tz_abbr) {
223 printf(" %s", d->tz_abbr);
224 }
225 /* Do we have a TimeZone struct? */
226 if (d->tz_info) {
227 printf(" %s", d->tz_info->name);
228 }
229 break;
230 case TIMELIB_ZONETYPE_ABBR:
231 printf(" %s", d->tz_abbr);
232 printf(" %05d%s", d->z, d->dst == 1 ? " (DST)" : "");
233 break;
234 }
235 }
236
237 if ((options & 1) == 1) {
238 if (d->have_relative) {
239 printf("%3lldY %3lldM %3lldD / %3lldH %3lldM %3lldS",
240 d->relative.y, d->relative.m, d->relative.d, d->relative.h, d->relative.i, d->relative.s);
241 if (d->relative.first_last_day_of != 0) {
242 switch (d->relative.first_last_day_of) {
243 case 1:
244 printf(" / first day of");
245 break;
246 case 2:
247 printf(" / last day of");
248 break;
249 }
250 }
251 if (d->relative.have_weekday_relative) {
252 printf(" / %d.%d", d->relative.weekday, d->relative.weekday_behavior);
253 }
254 if (d->relative.have_special_relative) {
255 switch (d->relative.special.type) {
256 case TIMELIB_SPECIAL_WEEKDAY:
257 printf(" / %lld weekday", d->relative.special.amount);
258 break;
259 case TIMELIB_SPECIAL_DAY_OF_WEEK_IN_MONTH:
260 printf(" / x y of z month");
261 break;
262 case TIMELIB_SPECIAL_LAST_DAY_OF_WEEK_IN_MONTH:
263 printf(" / last y of z month");
264 break;
265 }
266 }
267 }
268 }
269 printf("\n");
270 }
271
timelib_dump_rel_time(timelib_rel_time * d)272 void timelib_dump_rel_time(timelib_rel_time *d)
273 {
274 printf("%3lldY %3lldM %3lldD / %3lldH %3lldM %3lldS (days: %lld)%s",
275 d->y, d->m, d->d, d->h, d->i, d->s, d->days, d->invert ? " inverted" : "");
276 if (d->first_last_day_of != 0) {
277 switch (d->first_last_day_of) {
278 case 1:
279 printf(" / first day of");
280 break;
281 case 2:
282 printf(" / last day of");
283 break;
284 }
285 }
286 printf("\n");
287 }
288
timelib_parse_tz_cor(char ** ptr)289 long timelib_parse_tz_cor(char **ptr)
290 {
291 char *begin = *ptr, *end;
292 long tmp;
293
294 while (isdigit(**ptr) || **ptr == ':') {
295 ++*ptr;
296 }
297 end = *ptr;
298 switch (end - begin) {
299 case 1:
300 case 2:
301 return HOUR(strtol(begin, NULL, 10));
302 break;
303 case 3:
304 case 4:
305 if (begin[1] == ':') {
306 tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
307 return tmp;
308 } else if (begin[2] == ':') {
309 tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
310 return tmp;
311 } else {
312 tmp = strtol(begin, NULL, 10);
313 return HOUR(tmp / 100) + tmp % 100;
314 }
315 case 5:
316 tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
317 return tmp;
318 }
319 return 0;
320 }
321