1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2007 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: timelib.c,v 1.7.2.4.2.2 2007/01/01 09:35:59 sebastian Exp $ */
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 : timelib_time* timelib_time_ctor()
32 3 : {
33 : timelib_time *t;
34 3 : t = calloc(1, sizeof(timelib_time));
35 :
36 3 : return t;
37 : }
38 :
39 : void timelib_time_tz_abbr_update(timelib_time* tm, char* tz_abbr)
40 3 : {
41 : unsigned int i;
42 :
43 3 : TIMELIB_TIME_FREE(tm->tz_abbr);
44 3 : tm->tz_abbr = strdup(tz_abbr);
45 13 : for (i = 0; i < strlen(tz_abbr); i++) {
46 10 : tm->tz_abbr[i] = toupper(tz_abbr[i]);
47 : }
48 3 : }
49 :
50 : void timelib_time_dtor(timelib_time* t)
51 3 : {
52 3 : TIMELIB_TIME_FREE(t->tz_abbr);
53 3 : TIMELIB_TIME_FREE(t);
54 3 : }
55 :
56 : timelib_time_offset* timelib_time_offset_ctor()
57 3 : {
58 : timelib_time_offset *t;
59 3 : t = calloc(1, sizeof(timelib_time_offset));
60 :
61 3 : return t;
62 : }
63 :
64 : void timelib_time_offset_dtor(timelib_time_offset* t)
65 3 : {
66 3 : TIMELIB_TIME_FREE(t->abbr);
67 3 : TIMELIB_TIME_FREE(t);
68 3 : }
69 :
70 : timelib_tzinfo* timelib_tzinfo_ctor(char *name)
71 3 : {
72 : timelib_tzinfo *t;
73 3 : t = calloc(1, sizeof(timelib_tzinfo));
74 3 : t->name = strdup(name);
75 :
76 3 : return t;
77 : }
78 :
79 : timelib_tzinfo *timelib_tzinfo_clone(timelib_tzinfo *tz)
80 1 : {
81 1 : timelib_tzinfo *tmp = timelib_tzinfo_ctor(tz->name);
82 1 : tmp->ttisgmtcnt = tz->ttisgmtcnt;
83 1 : tmp->ttisstdcnt = tz->ttisstdcnt;
84 1 : tmp->leapcnt = tz->leapcnt;
85 1 : tmp->timecnt = tz->timecnt;
86 1 : tmp->typecnt = tz->typecnt;
87 1 : tmp->charcnt = tz->charcnt;
88 :
89 1 : tmp->trans = (int32_t *) malloc(tz->timecnt * sizeof(int32_t));
90 1 : tmp->trans_idx = (unsigned char*) malloc(tz->timecnt * sizeof(unsigned char));
91 1 : memcpy(tmp->trans, tz->trans, tz->timecnt * sizeof(int32_t));
92 1 : memcpy(tmp->trans_idx, tz->trans_idx, tz->timecnt * sizeof(unsigned char));
93 :
94 1 : tmp->type = (ttinfo*) malloc(tz->typecnt * sizeof(struct ttinfo));
95 1 : memcpy(tmp->type, tz->type, tz->typecnt * sizeof(struct ttinfo));
96 :
97 1 : tmp->timezone_abbr = (char*) malloc(tz->charcnt);
98 1 : memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->charcnt);
99 :
100 1 : tmp->leap_times = (tlinfo*) malloc(tz->leapcnt * sizeof(tlinfo));
101 1 : memcpy(tmp->leap_times, tz->leap_times, tz->leapcnt * sizeof(tlinfo));
102 :
103 1 : return tmp;
104 : }
105 :
106 : void timelib_tzinfo_dtor(timelib_tzinfo *tz)
107 3 : {
108 3 : TIMELIB_TIME_FREE(tz->name);
109 3 : TIMELIB_TIME_FREE(tz->trans);
110 3 : TIMELIB_TIME_FREE(tz->trans_idx);
111 3 : TIMELIB_TIME_FREE(tz->type);
112 3 : TIMELIB_TIME_FREE(tz->timezone_abbr);
113 3 : TIMELIB_TIME_FREE(tz->leap_times);
114 3 : TIMELIB_TIME_FREE(tz);
115 3 : }
116 :
117 : char *timelib_get_tz_abbr_ptr(timelib_time *t)
118 0 : {
119 0 : if (!t->sse_uptodate) {
120 0 : timelib_update_ts(t, NULL);
121 : };
122 0 : return t->tz_abbr;
123 : }
124 :
125 : void timelib_error_container_dtor(timelib_error_container *errors)
126 1 : {
127 : int i;
128 :
129 1 : for (i = 0; i < errors->warning_count; i++) {
130 0 : free(errors->warning_messages[i].message);
131 : }
132 1 : free(errors->warning_messages);
133 1 : for (i = 0; i < errors->error_count; i++) {
134 0 : free(errors->error_messages[i].message);
135 : }
136 1 : free(errors->error_messages);
137 1 : free(errors);
138 1 : }
139 :
140 : signed long timelib_date_to_int(timelib_time *d, int *error)
141 1 : {
142 : timelib_sll ts;
143 :
144 1 : ts = d->sse;
145 :
146 1 : if (ts < LONG_MIN || ts > LONG_MAX) {
147 0 : if (error) {
148 0 : *error = 1;
149 : }
150 0 : return 0;
151 : }
152 1 : if (error) {
153 1 : *error = 0;
154 : }
155 1 : return (signed long) d->sse;
156 : }
157 :
158 : void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec)
159 0 : {
160 0 : *hour = floor(h);
161 0 : *min = floor((h - *hour) * 60);
162 0 : *sec = (h - *hour - ((float) *min / 60)) * 3600;
163 0 : }
164 :
165 : void timelib_dump_date(timelib_time *d, int options)
166 0 : {
167 0 : if ((options & 2) == 2) {
168 0 : printf("TYPE: %d ", d->zone_type);
169 : }
170 0 : printf("TS: %lld | %04lld-%02lld-%02lld %02lld:%02lld:%02lld",
171 : d->sse, d->y, d->m, d->d, d->h, d->i, d->s);
172 0 : if (d->f > +0.0) {
173 0 : printf(" %.5f", d->f);
174 : }
175 :
176 0 : if (d->is_localtime) {
177 0 : switch (d->zone_type) {
178 : case TIMELIB_ZONETYPE_OFFSET: /* Only offset */
179 0 : printf(" GMT %05d%s", d->z, d->dst == 1 ? " (DST)" : "");
180 0 : break;
181 : case TIMELIB_ZONETYPE_ID: /* Timezone struct */
182 : /* Show abbreviation if wanted */
183 0 : if (d->tz_abbr) {
184 0 : printf(" %s", d->tz_abbr);
185 : }
186 : /* Do we have a TimeZone struct? */
187 0 : if (d->tz_info) {
188 0 : printf(" %s", d->tz_info->name);
189 : }
190 0 : break;
191 : case TIMELIB_ZONETYPE_ABBR:
192 0 : printf(" %s", d->tz_abbr);
193 0 : printf(" %05d%s", d->z, d->dst == 1 ? " (DST)" : "");
194 : break;
195 : }
196 : } else {
197 0 : printf(" GMT 00000");
198 : }
199 :
200 0 : if ((options & 1) == 1) {
201 0 : if (d->have_relative) {
202 0 : printf("%3lldY %3lldM %3lldD / %3lldH %3lldM %3lldS",
203 : d->relative.y, d->relative.m, d->relative.d, d->relative.h, d->relative.i, d->relative.s);
204 : }
205 0 : if (d->have_weekday_relative) {
206 0 : printf(" / %d.%d", d->relative.weekday, d->relative.weekday_behavior);
207 : }
208 0 : if (d->have_special_relative) {
209 0 : switch (d->special.type) {
210 : case TIMELIB_SPECIAL_WEEKDAY:
211 0 : printf(" / %lld weekday", d->special.amount);
212 : break;
213 : }
214 : }
215 : }
216 0 : printf("\n");
217 0 : }
218 :
|