From: Derick Rethans Date: Mon, 3 Oct 2005 11:15:21 +0000 (+0000) Subject: - Allow an external Timezone Database to be used. X-Git-Tag: RELEASE_0_9_0~38 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b75871d017230a7904e89257765bd53c5c2f8d2f;p=php - Allow an external Timezone Database to be used. --- diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index 86271f2568..cabecdc3d8 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.9.10.dev on Sat Oct 1 17:04:46 2005 */ +/* Generated by re2c 0.9.10.dev on Mon Oct 3 13:09:17 2005 */ #line 1 "resource/parse_date.re" /* +----------------------------------------------------------------------+ @@ -144,6 +144,7 @@ typedef struct Scanner { int errors; struct timelib_time *time; + timelib_tzdb *tzdb; } Scanner; typedef struct _timelib_lookup_table { @@ -617,7 +618,7 @@ static long timelib_lookup_zone(char **ptr, int *dst, char **tz_abbr, int *found return value; } -static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found) +static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, timelib_tzdb *tzdb) { timelib_tzinfo *res; @@ -659,7 +660,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_ #endif /* If we have a TimeZone identifier to start with, use it */ if (strstr(tz_abbr, "/")) { - if ((res = timelib_parse_tzfile(tz_abbr)) != NULL) { + if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) { t->tz_info = res; t->zone_type = TIMELIB_ZONETYPE_ID; found++; @@ -692,7 +693,7 @@ static int scan(Scanner *s) std: s->tok = cursor; s->len = 0; -#line 798 "resource/parse_date.re" +#line 799 "resource/parse_date.re" { @@ -731,7 +732,7 @@ std: 0, 0, 0, 0, 0, 0, 0, 0, }; -#line 735 "" +#line 736 "" { YYCTYPE yych; unsigned int yyaccept; @@ -816,17 +817,17 @@ yy2: yy3: YYDEBUG(3, *YYCURSOR); -#line 1280 "resource/parse_date.re" +#line 1281 "resource/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("tzcorrection | tz"); TIMELIB_INIT; - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; TIMELIB_DEINIT; return TIMELIB_TIMEZONE; } -#line 823 "" +#line 824 "" yy4: YYDEBUG(4, *YYCURSOR); yych = *++YYCURSOR; @@ -912,13 +913,13 @@ yy6: yy7: YYDEBUG(7, *YYCURSOR); -#line 1346 "resource/parse_date.re" +#line 1347 "resource/parse_date.re" { /* printf("unexpected character: #%d, %c ", *s->tok, *s->tok); */ s->errors++; goto std; } -#line 906 "" +#line 907 "" yy8: YYDEBUG(8, *YYCURSOR); yyaccept = 0; @@ -1841,11 +1842,11 @@ yy43: yy44: YYDEBUG(44, *YYCURSOR); -#line 1335 "resource/parse_date.re" +#line 1336 "resource/parse_date.re" { goto std; } -#line 1754 "" +#line 1755 "" yy45: YYDEBUG(45, *YYCURSOR); ++YYCURSOR; @@ -1853,12 +1854,12 @@ yy45: yy46: YYDEBUG(46, *YYCURSOR); -#line 1340 "resource/parse_date.re" +#line 1341 "resource/parse_date.re" { s->pos = cursor; s->line++; goto std; } -#line 1763 "" +#line 1764 "" yy47: YYDEBUG(47, *YYCURSOR); yych = *++YYCURSOR; @@ -2316,7 +2317,7 @@ yy84: yy85: YYDEBUG(85, *YYCURSOR); -#line 1319 "resource/parse_date.re" +#line 1320 "resource/parse_date.re" { timelib_ull i; DEBUG_OUTPUT("relative"); @@ -2331,7 +2332,7 @@ yy85: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 2153 "" +#line 2154 "" yy86: YYDEBUG(86, *YYCURSOR); ++YYCURSOR; @@ -3024,12 +3025,12 @@ yy150: yy151: YYDEBUG(151, *YYCURSOR); -#line 1274 "resource/parse_date.re" +#line 1275 "resource/parse_date.re" { DEBUG_OUTPUT("dayabbr"); goto std; } -#line 2717 "" +#line 2718 "" yy152: YYDEBUG(152, *YYCURSOR); yyaccept = 1; @@ -3068,7 +3069,7 @@ yy157: yy158: YYDEBUG(158, *YYCURSOR); -#line 1258 "resource/parse_date.re" +#line 1259 "resource/parse_date.re" { const timelib_relunit* relunit; DEBUG_OUTPUT("dayfull"); @@ -3083,7 +3084,7 @@ yy158: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 2757 "" +#line 2758 "" yy159: YYDEBUG(159, *YYCURSOR); yyaccept = 1; @@ -3452,7 +3453,7 @@ yy189: yy190: YYDEBUG(190, *YYCURSOR); -#line 1242 "resource/parse_date.re" +#line 1243 "resource/parse_date.re" { timelib_sll i; DEBUG_OUTPUT("relativetext"); @@ -3467,7 +3468,7 @@ yy190: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 3075 "" +#line 3076 "" yy191: YYDEBUG(191, *YYCURSOR); ++YYCURSOR; @@ -9097,7 +9098,7 @@ yy508: yy509: YYDEBUG(509, *YYCURSOR); -#line 1064 "resource/parse_date.re" +#line 1065 "resource/parse_date.re" { DEBUG_OUTPUT("datetextual | datenoyear"); TIMELIB_INIT; @@ -9109,7 +9110,7 @@ yy509: TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 8068 "" +#line 8069 "" yy510: YYDEBUG(510, *YYCURSOR); yych = *++YYCURSOR; @@ -9269,7 +9270,7 @@ yy526: yy527: YYDEBUG(527, *YYCURSOR); -#line 1291 "resource/parse_date.re" +#line 1292 "resource/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz"); @@ -9290,13 +9291,13 @@ yy527: } if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; return TIMELIB_SHORTDATE_WITH_TIME; } -#line 8219 "" +#line 8220 "" yy528: YYDEBUG(528, *YYCURSOR); yyaccept = 7; @@ -9609,7 +9610,7 @@ yy561: yy562: YYDEBUG(562, *YYCURSOR); -#line 1038 "resource/parse_date.re" +#line 1039 "resource/parse_date.re" { DEBUG_OUTPUT("datenoday"); TIMELIB_INIT; @@ -9621,7 +9622,7 @@ yy562: TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } -#line 8474 "" +#line 8475 "" yy563: YYDEBUG(563, *YYCURSOR); yyaccept = 6; @@ -9921,7 +9922,7 @@ yy587: yy588: YYDEBUG(588, *YYCURSOR); -#line 1173 "resource/parse_date.re" +#line 1174 "resource/parse_date.re" { DEBUG_OUTPUT("pgtextshort"); TIMELIB_INIT; @@ -9933,7 +9934,7 @@ yy588: TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } -#line 8733 "" +#line 8734 "" yy589: YYDEBUG(589, *YYCURSOR); yych = *++YYCURSOR; @@ -11437,7 +11438,7 @@ yy683: yy684: YYDEBUG(684, *YYCURSOR); -#line 1227 "resource/parse_date.re" +#line 1228 "resource/parse_date.re" { DEBUG_OUTPUT("ago"); TIMELIB_INIT; @@ -11451,7 +11452,7 @@ yy684: TIMELIB_DEINIT; return TIMELIB_AGO; } -#line 10058 "" +#line 10059 "" yy685: YYDEBUG(685, *YYCURSOR); yyaccept = 1; @@ -13385,7 +13386,7 @@ yy787: yy788: YYDEBUG(788, *YYCURSOR); -#line 1077 "resource/parse_date.re" +#line 1078 "resource/parse_date.re" { DEBUG_OUTPUT("datenoyearrev"); TIMELIB_INIT; @@ -13395,7 +13396,7 @@ yy788: TIMELIB_DEINIT; return TIMELIB_DATE_TEXT; } -#line 11790 "" +#line 11791 "" yy789: YYDEBUG(789, *YYCURSOR); yyaccept = 10; @@ -13488,7 +13489,7 @@ yy796: yy797: YYDEBUG(797, *YYCURSOR); -#line 885 "resource/parse_date.re" +#line 886 "resource/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long"); @@ -13505,13 +13506,13 @@ yy797: } if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; return TIMELIB_TIME24_WITH_ZONE; } -#line 11888 "" +#line 11889 "" yy798: YYDEBUG(798, *YYCURSOR); yyaccept = 11; @@ -13639,7 +13640,7 @@ yy811: yy812: YYDEBUG(812, *YYCURSOR); -#line 870 "resource/parse_date.re" +#line 871 "resource/parse_date.re" { DEBUG_OUTPUT("timeshort12 | timelong12"); TIMELIB_INIT; @@ -13653,7 +13654,7 @@ yy812: TIMELIB_DEINIT; return TIMELIB_TIME12; } -#line 12000 "" +#line 12001 "" yy813: YYDEBUG(813, *YYCURSOR); yych = *++YYCURSOR; @@ -13776,7 +13777,7 @@ yy824: yy825: YYDEBUG(825, *YYCURSOR); -#line 1012 "resource/parse_date.re" +#line 1013 "resource/parse_date.re" { DEBUG_OUTPUT("datefull"); TIMELIB_INIT; @@ -13788,7 +13789,7 @@ yy825: TIMELIB_DEINIT; return TIMELIB_DATE_FULL; } -#line 12109 "" +#line 12110 "" yy826: YYDEBUG(826, *YYCURSOR); yych = *++YYCURSOR; @@ -14407,7 +14408,7 @@ yy892: yy893: YYDEBUG(893, *YYCURSOR); -#line 1025 "resource/parse_date.re" +#line 1026 "resource/parse_date.re" { DEBUG_OUTPUT("pointed date"); TIMELIB_INIT; @@ -14419,7 +14420,7 @@ yy893: TIMELIB_DEINIT; return TIMELIB_DATE_FULL_POINTED; } -#line 12604 "" +#line 12605 "" yy894: YYDEBUG(894, *YYCURSOR); yych = *++YYCURSOR; @@ -14987,7 +14988,7 @@ yy938: yy939: YYDEBUG(939, *YYCURSOR); -#line 999 "resource/parse_date.re" +#line 1000 "resource/parse_date.re" { DEBUG_OUTPUT("gnudateshort"); TIMELIB_INIT; @@ -14999,7 +15000,7 @@ yy939: TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 13092 "" +#line 13093 "" yy940: YYDEBUG(940, *YYCURSOR); yych = *++YYCURSOR; @@ -15021,7 +15022,7 @@ yy942: yy943: YYDEBUG(943, *YYCURSOR); -#line 972 "resource/parse_date.re" +#line 973 "resource/parse_date.re" { DEBUG_OUTPUT("americanshort | american"); TIMELIB_INIT; @@ -15035,7 +15036,7 @@ yy943: TIMELIB_DEINIT; return TIMELIB_AMERICAN; } -#line 13120 "" +#line 13121 "" yy944: YYDEBUG(944, *YYCURSOR); yyaccept = 12; @@ -15257,7 +15258,7 @@ yy975: yy976: YYDEBUG(976, *YYCURSOR); -#line 1199 "resource/parse_date.re" +#line 1200 "resource/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("clf"); @@ -15270,12 +15271,12 @@ yy976: s->time->h = timelib_get_nr((char **) &ptr, 2); s->time->i = timelib_get_nr((char **) &ptr, 2); s->time->s = timelib_get_nr((char **) &ptr, 2); - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; TIMELIB_DEINIT; return TIMELIB_CLF; } -#line 13294 "" +#line 13295 "" yy977: YYDEBUG(977, *YYCURSOR); yyaccept = 13; @@ -15584,7 +15585,7 @@ yy1015: yy1016: YYDEBUG(1016, *YYCURSOR); -#line 1186 "resource/parse_date.re" +#line 1187 "resource/parse_date.re" { DEBUG_OUTPUT("pgtextreverse"); TIMELIB_INIT; @@ -15596,7 +15597,7 @@ yy1016: TIMELIB_DEINIT; return TIMELIB_PG_TEXT; } -#line 13534 "" +#line 13535 "" yy1017: YYDEBUG(1017, *YYCURSOR); yych = *++YYCURSOR; @@ -15729,7 +15730,7 @@ yy1027: yy1028: YYDEBUG(1028, *YYCURSOR); -#line 1218 "resource/parse_date.re" +#line 1219 "resource/parse_date.re" { DEBUG_OUTPUT("year4"); TIMELIB_INIT; @@ -15737,7 +15738,7 @@ yy1028: TIMELIB_DEINIT; return TIMELIB_CLF; } -#line 13650 "" +#line 13651 "" yy1029: YYDEBUG(1029, *YYCURSOR); yych = *++YYCURSOR; @@ -15873,7 +15874,7 @@ yy1036: yy1037: YYDEBUG(1037, *YYCURSOR); -#line 1051 "resource/parse_date.re" +#line 1052 "resource/parse_date.re" { DEBUG_OUTPUT("datenodayrev"); TIMELIB_INIT; @@ -15885,7 +15886,7 @@ yy1037: TIMELIB_DEINIT; return TIMELIB_DATE_NO_DAY; } -#line 13777 "" +#line 13778 "" yy1038: YYDEBUG(1038, *YYCURSOR); yych = *++YYCURSOR; @@ -16094,7 +16095,7 @@ yy1056: yy1057: YYDEBUG(1057, *YYCURSOR); -#line 1154 "resource/parse_date.re" +#line 1155 "resource/parse_date.re" { timelib_sll w, d; DEBUG_OUTPUT("isoweek"); @@ -16112,7 +16113,7 @@ yy1057: TIMELIB_DEINIT; return TIMELIB_ISO_WEEK; } -#line 13964 "" +#line 13965 "" yy1058: YYDEBUG(1058, *YYCURSOR); ++YYCURSOR; @@ -16120,7 +16121,7 @@ yy1058: yy1059: YYDEBUG(1059, *YYCURSOR); -#line 1135 "resource/parse_date.re" +#line 1136 "resource/parse_date.re" { timelib_sll w, d; DEBUG_OUTPUT("isoweekday"); @@ -16138,7 +16139,7 @@ yy1059: TIMELIB_DEINIT; return TIMELIB_ISO_WEEK; } -#line 13986 "" +#line 13987 "" yy1060: YYDEBUG(1060, *YYCURSOR); yych = *++YYCURSOR; @@ -16207,7 +16208,7 @@ yy1062: yy1063: YYDEBUG(1063, *YYCURSOR); -#line 1122 "resource/parse_date.re" +#line 1123 "resource/parse_date.re" { DEBUG_OUTPUT("pgydotd"); TIMELIB_INIT; @@ -16219,7 +16220,7 @@ yy1063: TIMELIB_DEINIT; return TIMELIB_PG_YEARDAY; } -#line 14059 "" +#line 14060 "" yy1064: YYDEBUG(1064, *YYCURSOR); yych = *++YYCURSOR; @@ -16334,7 +16335,7 @@ yy1069: yy1070: YYDEBUG(1070, *YYCURSOR); -#line 1088 "resource/parse_date.re" +#line 1089 "resource/parse_date.re" { DEBUG_OUTPUT("datenocolon"); TIMELIB_INIT; @@ -16345,7 +16346,7 @@ yy1070: TIMELIB_DEINIT; return TIMELIB_DATE_NOCOLON; } -#line 14167 "" +#line 14168 "" yy1071: YYDEBUG(1071, *YYCURSOR); yych = *++YYCURSOR; @@ -16443,7 +16444,7 @@ yy1080: yy1081: YYDEBUG(1081, *YYCURSOR); -#line 1100 "resource/parse_date.re" +#line 1101 "resource/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx"); @@ -16458,13 +16459,13 @@ yy1081: s->time->s = timelib_get_nr((char **) &ptr, 2); if (*ptr == '.') { s->time->f = timelib_get_frac_nr((char **) &ptr, 9); - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; return TIMELIB_XMLRPC_SOAP; } -#line 14264 "" +#line 14265 "" yy1082: YYDEBUG(1082, *YYCURSOR); yych = *++YYCURSOR; @@ -17067,7 +17068,7 @@ yy1171: yy1172: YYDEBUG(1172, *YYCURSOR); -#line 987 "resource/parse_date.re" +#line 988 "resource/parse_date.re" { DEBUG_OUTPUT("iso8601date | iso8601dateslash | dateslash"); TIMELIB_INIT; @@ -17078,7 +17079,7 @@ yy1172: TIMELIB_DEINIT; return TIMELIB_ISO_DATE; } -#line 14696 "" +#line 14697 "" yy1173: YYDEBUG(1173, *YYCURSOR); yych = *++YYCURSOR; @@ -17851,7 +17852,7 @@ yy1262: yy1263: YYDEBUG(1263, *YYCURSOR); -#line 909 "resource/parse_date.re" +#line 910 "resource/parse_date.re" { DEBUG_OUTPUT("gnunocolon"); TIMELIB_INIT; @@ -17872,7 +17873,7 @@ yy1263: TIMELIB_DEINIT; return TIMELIB_GNU_NOCOLON; } -#line 15306 "" +#line 15307 "" yy1264: YYDEBUG(1264, *YYCURSOR); yych = *++YYCURSOR; @@ -17969,7 +17970,7 @@ yy1270: yy1271: YYDEBUG(1271, *YYCURSOR); -#line 954 "resource/parse_date.re" +#line 955 "resource/parse_date.re" { int tz_not_found; DEBUG_OUTPUT("iso8601nocolon"); @@ -17980,13 +17981,13 @@ yy1271: s->time->s = timelib_get_nr((char **) &ptr, 2); if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; return TIMELIB_ISO_NOCOLON; } -#line 15404 "" +#line 15405 "" yy1272: YYDEBUG(1272, *YYCURSOR); yyaccept = 21; @@ -18283,7 +18284,7 @@ yy1295: yy1296: YYDEBUG(1296, *YYCURSOR); -#line 846 "resource/parse_date.re" +#line 847 "resource/parse_date.re" { timelib_ull i; @@ -18306,7 +18307,7 @@ yy1296: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 15668 "" +#line 15669 "" yy1297: YYDEBUG(1297, *YYCURSOR); yych = *++YYCURSOR; @@ -18377,7 +18378,7 @@ yy1304: yy1305: YYDEBUG(1305, *YYCURSOR); -#line 834 "resource/parse_date.re" +#line 835 "resource/parse_date.re" { DEBUG_OUTPUT("tomorrow"); TIMELIB_INIT; @@ -18388,7 +18389,7 @@ yy1305: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 15732 "" +#line 15733 "" yy1306: YYDEBUG(1306, *YYCURSOR); yych = *++YYCURSOR; @@ -18401,7 +18402,7 @@ yy1307: yy1308: YYDEBUG(1308, *YYCURSOR); -#line 824 "resource/parse_date.re" +#line 825 "resource/parse_date.re" { DEBUG_OUTPUT("today"); TIMELIB_INIT; @@ -18410,7 +18411,7 @@ yy1308: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 15748 "" +#line 15749 "" yy1309: YYDEBUG(1309, *YYCURSOR); yych = *++YYCURSOR; @@ -18444,7 +18445,7 @@ yy1310: yy1311: YYDEBUG(1311, *YYCURSOR); -#line 815 "resource/parse_date.re" +#line 816 "resource/parse_date.re" { DEBUG_OUTPUT("now"); TIMELIB_INIT; @@ -18452,7 +18453,7 @@ yy1311: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 15784 "" +#line 15785 "" yy1312: YYDEBUG(1312, *YYCURSOR); yych = *++YYCURSOR; @@ -18510,7 +18511,7 @@ yy1319: yy1320: YYDEBUG(1320, *YYCURSOR); -#line 803 "resource/parse_date.re" +#line 804 "resource/parse_date.re" { DEBUG_OUTPUT("yesterday"); TIMELIB_INIT; @@ -18521,17 +18522,17 @@ yy1320: TIMELIB_DEINIT; return TIMELIB_RELATIVE; } -#line 15835 "" +#line 15836 "" } } -#line 1351 "resource/parse_date.re" +#line 1352 "resource/parse_date.re" } #define YYMAXFILL 26 -timelib_time* timelib_strtotime(char *s, int *errors) +timelib_time* timelib_strtotime(char *s, int *errors, timelib_tzdb *tzdb) { Scanner in; int t; @@ -18553,6 +18554,7 @@ timelib_time* timelib_strtotime(char *s, int *errors) in.time->z = -1; in.time->dst = -1; in.errors = 0; + in.tzdb = tzdb; do { t = scan(&in); diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re index f5ca76b12a..96b0855a67 100644 --- a/ext/date/lib/parse_date.re +++ b/ext/date/lib/parse_date.re @@ -142,6 +142,7 @@ typedef struct Scanner { int errors; struct timelib_time *time; + timelib_tzdb *tzdb; } Scanner; typedef struct _timelib_lookup_table { @@ -615,7 +616,7 @@ static long timelib_lookup_zone(char **ptr, int *dst, char **tz_abbr, int *found return value; } -static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found) +static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, timelib_tzdb *tzdb) { timelib_tzinfo *res; @@ -657,7 +658,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_ #endif /* If we have a TimeZone identifier to start with, use it */ if (strstr(tz_abbr, "/")) { - if ((res = timelib_parse_tzfile(tz_abbr)) != NULL) { + if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) { t->tz_info = res; t->zone_type = TIMELIB_ZONETYPE_ID; found++; @@ -898,7 +899,7 @@ relativetext = (reltextnumber space? reltextunit)+; } if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; @@ -936,7 +937,7 @@ relativetext = (reltextnumber space? reltextunit)+; s->time->h = timelib_get_nr((char **) &ptr, 2); s->time->i = timelib_get_nr((char **) &ptr, 2); s->time->s = 0; - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, s->tzdb); break; case 1: s->time->y = timelib_get_nr((char **) &ptr, 4); @@ -961,7 +962,7 @@ relativetext = (reltextnumber space? reltextunit)+; s->time->s = timelib_get_nr((char **) &ptr, 2); if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; @@ -1111,7 +1112,7 @@ relativetext = (reltextnumber space? reltextunit)+; s->time->s = timelib_get_nr((char **) &ptr, 2); if (*ptr == '.') { s->time->f = timelib_get_frac_nr((char **) &ptr, 9); - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; @@ -1208,7 +1209,7 @@ relativetext = (reltextnumber space? reltextunit)+; s->time->h = timelib_get_nr((char **) &ptr, 2); s->time->i = timelib_get_nr((char **) &ptr, 2); s->time->s = timelib_get_nr((char **) &ptr, 2); - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; TIMELIB_DEINIT; return TIMELIB_CLF; @@ -1281,7 +1282,7 @@ relativetext = (reltextnumber space? reltextunit)+; int tz_not_found; DEBUG_OUTPUT("tzcorrection | tz"); TIMELIB_INIT; - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; TIMELIB_DEINIT; return TIMELIB_TIMEZONE; @@ -1308,7 +1309,7 @@ relativetext = (reltextnumber space? reltextunit)+; } if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; @@ -1353,7 +1354,7 @@ relativetext = (reltextnumber space? reltextunit)+; /*!max:re2c */ -timelib_time* timelib_strtotime(char *s, int *errors) +timelib_time* timelib_strtotime(char *s, int *errors, timelib_tzdb *tzdb) { Scanner in; int t; @@ -1375,6 +1376,7 @@ timelib_time* timelib_strtotime(char *s, int *errors) in.time->z = -1; in.time->dst = -1; in.errors = 0; + in.tzdb = tzdb; do { t = scan(&in); diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c index 7a6e683eb1..f4eaee36b5 100644 --- a/ext/date/lib/parse_tz.c +++ b/ext/date/lib/parse_tz.c @@ -192,7 +192,7 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz) } } -static int tz_search(char *timezone, int left, int right) +static int tz_search(char *timezone, int left, int right, timelib_tzdb *tzdb) { int mid, cmp; @@ -202,41 +202,48 @@ static int tz_search(char *timezone, int left, int right) mid = (left + right) / 2; - cmp = strcasecmp(timezone, timezonedb_idx[mid].id); + cmp = strcasecmp(timezone, tzdb->index[mid].id); if (cmp < 0) { - return tz_search(timezone, left, mid - 1); + return tz_search(timezone, left, mid - 1, tzdb); } else if (cmp > 0) { - return tz_search(timezone, mid + 1, right); + return tz_search(timezone, mid + 1, right, tzdb); } else { /* (cmp == 0) */ - return timezonedb_idx[mid].pos; + return tzdb->index[mid].pos; } } -static int seek_to_tz_position(char **tzf, char *timezone) +static int seek_to_tz_position(char **tzf, char *timezone, timelib_tzdb *tzdb) { - int pos = tz_search(timezone, 0, sizeof(timezonedb_idx)/sizeof(*timezonedb_idx)-1); + int pos; + + pos = tz_search(timezone, 0, tzdb->index_size, tzdb); if (pos == -1) { return 0; } - (*tzf) = &timelib_timezone_db_data[pos + 20]; + (*tzf) = &(tzdb->data[pos + 20]); return 1; } -timelib_tzdb_index_entry *timelib_timezone_identifiers_list(int *count) +timelib_tzdb *timelib_builtin_db(void) +{ + return &timezonedb_builtin; +} + +timelib_tzdb_index_entry *timelib_timezone_builtin_identifiers_list(int *count) { - *count = sizeof(timezonedb_idx) / sizeof(*timezonedb_idx); - return timezonedb_idx; + *count = sizeof(timezonedb_idx_builtin) / sizeof(*timezonedb_idx_builtin); + return timezonedb_idx_builtin; } -timelib_tzinfo *timelib_parse_tzfile(char *timezone) +timelib_tzinfo *timelib_parse_tzfile(char *timezone, timelib_tzdb *tzdb) { char *tzf; timelib_tzinfo *tmp; - if (seek_to_tz_position((char**) &tzf, timezone)) { + if (seek_to_tz_position((char**) &tzf, timezone, tzdb)) { tmp = timelib_tzinfo_ctor(timezone); read_header((char**) &tzf, tmp); diff --git a/ext/date/lib/resource/parse_date.re b/ext/date/lib/resource/parse_date.re index f5ca76b12a..96b0855a67 100644 --- a/ext/date/lib/resource/parse_date.re +++ b/ext/date/lib/resource/parse_date.re @@ -142,6 +142,7 @@ typedef struct Scanner { int errors; struct timelib_time *time; + timelib_tzdb *tzdb; } Scanner; typedef struct _timelib_lookup_table { @@ -615,7 +616,7 @@ static long timelib_lookup_zone(char **ptr, int *dst, char **tz_abbr, int *found return value; } -static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found) +static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_found, timelib_tzdb *tzdb) { timelib_tzinfo *res; @@ -657,7 +658,7 @@ static long timelib_get_zone(char **ptr, int *dst, timelib_time *t, int *tz_not_ #endif /* If we have a TimeZone identifier to start with, use it */ if (strstr(tz_abbr, "/")) { - if ((res = timelib_parse_tzfile(tz_abbr)) != NULL) { + if ((res = timelib_parse_tzfile(tz_abbr, tzdb)) != NULL) { t->tz_info = res; t->zone_type = TIMELIB_ZONETYPE_ID; found++; @@ -898,7 +899,7 @@ relativetext = (reltextnumber space? reltextunit)+; } if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; @@ -936,7 +937,7 @@ relativetext = (reltextnumber space? reltextunit)+; s->time->h = timelib_get_nr((char **) &ptr, 2); s->time->i = timelib_get_nr((char **) &ptr, 2); s->time->s = 0; - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, s->tzdb); break; case 1: s->time->y = timelib_get_nr((char **) &ptr, 4); @@ -961,7 +962,7 @@ relativetext = (reltextnumber space? reltextunit)+; s->time->s = timelib_get_nr((char **) &ptr, 2); if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; @@ -1111,7 +1112,7 @@ relativetext = (reltextnumber space? reltextunit)+; s->time->s = timelib_get_nr((char **) &ptr, 2); if (*ptr == '.') { s->time->f = timelib_get_frac_nr((char **) &ptr, 9); - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; @@ -1208,7 +1209,7 @@ relativetext = (reltextnumber space? reltextunit)+; s->time->h = timelib_get_nr((char **) &ptr, 2); s->time->i = timelib_get_nr((char **) &ptr, 2); s->time->s = timelib_get_nr((char **) &ptr, 2); - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; TIMELIB_DEINIT; return TIMELIB_CLF; @@ -1281,7 +1282,7 @@ relativetext = (reltextnumber space? reltextunit)+; int tz_not_found; DEBUG_OUTPUT("tzcorrection | tz"); TIMELIB_INIT; - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; TIMELIB_DEINIT; return TIMELIB_TIMEZONE; @@ -1308,7 +1309,7 @@ relativetext = (reltextnumber space? reltextunit)+; } if (*ptr != '\0') { - s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found); + s->time->z = timelib_get_zone((char **) &ptr, &s->time->dst, s->time, &tz_not_found, s->tzdb); s->errors += tz_not_found; } TIMELIB_DEINIT; @@ -1353,7 +1354,7 @@ relativetext = (reltextnumber space? reltextunit)+; /*!max:re2c */ -timelib_time* timelib_strtotime(char *s, int *errors) +timelib_time* timelib_strtotime(char *s, int *errors, timelib_tzdb *tzdb) { Scanner in; int t; @@ -1375,6 +1376,7 @@ timelib_time* timelib_strtotime(char *s, int *errors) in.time->z = -1; in.time->dst = -1; in.errors = 0; + in.tzdb = tzdb; do { t = scan(&in); diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index 8e6f5a7244..faa99df223 100644 --- a/ext/date/lib/timelib.h +++ b/ext/date/lib/timelib.h @@ -47,7 +47,7 @@ timelib_sll timelib_days_in_month(timelib_sll y, timelib_sll m); void timelib_isoweek_from_date(timelib_sll y, timelib_sll m, timelib_sll d, timelib_sll *iw, timelib_sll *iy); /* From parse_date.re */ -timelib_time *timelib_strtotime(char *s, int *errors); +timelib_time *timelib_strtotime(char *s, int *errors, timelib_tzdb *tzdb); void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options); char *timelib_timezone_id_from_abbr(const char *abbr, long gmtoffset, int isdst); timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void); @@ -63,11 +63,12 @@ void timelib_update_from_sse(timelib_time *tm); void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz); /* From parse_tz.c */ -timelib_tzinfo *timelib_parse_tzfile(char *timezone); +timelib_tzinfo *timelib_parse_tzfile(char *timezone, timelib_tzdb *tzdb); int timelib_timestamp_is_in_dst(timelib_sll ts, timelib_tzinfo *tz); timelib_time_offset *timelib_get_time_zone_info(timelib_sll ts, timelib_tzinfo *tz); void timelib_dump_tzinfo(timelib_tzinfo *tz); -timelib_tzdb_index_entry *timelib_timezone_identifiers_list(int *count); +timelib_tzdb *timelib_builtin_db(void); +timelib_tzdb_index_entry *timelib_timezone_builtin_identifiers_list(int *count); /* From timelib.c */ timelib_tzinfo* timelib_tzinfo_ctor(); @@ -77,6 +78,7 @@ void timelib_tzinfo_dtor(timelib_tzinfo *tz); timelib_tzinfo* timelib_tzinfo_clone(timelib_tzinfo *tz); timelib_time* timelib_time_ctor(); +void timelib_time_set_option(timelib_time* tm, int option, void* option_value); void timelib_time_dtor(timelib_time* t); timelib_time_offset* timelib_time_offset_ctor(); diff --git a/ext/date/lib/timelib_structs.h b/ext/date/lib/timelib_structs.h index dfaf72a680..a32d9f6f0f 100644 --- a/ext/date/lib/timelib_structs.h +++ b/ext/date/lib/timelib_structs.h @@ -21,7 +21,7 @@ #ifndef __TIMELIB_STRUCTS_H__ #define __TIMELIB_STRUCTS_H__ -#include +#include "timelib_config.h" #ifdef HAVE_SYS_TYPES_H #include @@ -158,6 +158,13 @@ typedef struct _timelib_tzdb_index_entry { unsigned int pos; } timelib_tzdb_index_entry; +typedef struct _timelib_tzdb { + char *version; + int index_size; + timelib_tzdb_index_entry *index; + char *data; +} timelib_tzdb; + #define TIMELIB_ZONETYPE_OFFSET 1 #define TIMELIB_ZONETYPE_ABBR 2 #define TIMELIB_ZONETYPE_ID 3 diff --git a/ext/date/lib/timezonedb.h b/ext/date/lib/timezonedb.h index 35745977f9..1d950045bd 100644 --- a/ext/date/lib/timezonedb.h +++ b/ext/date/lib/timezonedb.h @@ -1,4 +1,4 @@ -timelib_tzdb_index_entry timezonedb_idx[535] = { +timelib_tzdb_index_entry timezonedb_idx_builtin[535] = { { "Africa/Abidjan" , 0x000000 }, { "Africa/Accra" , 0x000049 }, { "Africa/Addis_Ababa" , 0x0000E5 }, @@ -536,7 +536,7 @@ timelib_tzdb_index_entry timezonedb_idx[535] = { { "Zulu" , 0x038E5D }, }; /* This is a generated file, do not modify */ -unsigned char timelib_timezone_db_data[233109] = { +unsigned char timelib_timezone_db_data_builtin[233109] = { /* Africa/Abidjan */ @@ -16451,3 +16451,5 @@ unsigned char timelib_timezone_db_data[233109] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x54, 0x43, 0x00, 0x00, 0x00, }; + +timelib_tzdb timezonedb_builtin = { "2005.13", 535, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 4fd5c62f92..856b2025cc 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -108,6 +108,10 @@ static char* guess_timezone(TSRMLS_D); ZEND_DECLARE_MODULE_GLOBALS(date) +/* True global */ +timelib_tzdb *php_date_global_timezone_db; +int php_date_global_timezone_db_enabled; + /* {{{ INI Settings */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("date.timezone", "", PHP_INI_ALL, OnUpdateString, default_timezone, zend_date_globals, date_globals) @@ -206,6 +210,8 @@ PHP_RSHUTDOWN_FUNCTION(date) } /* }}} */ +#define DATE_TIMEZONEDB php_date_global_timezone_db ? php_date_global_timezone_db : timelib_builtin_db() + #define DATE_FORMAT_ISO8601 "Y-m-d\\TH:i:sO" #define DATE_FORMAT_RFC1036 "l, d-M-y H:i:s T" #define DATE_FORMAT_RFC1123 "D, d M Y H:i:s T" @@ -230,6 +236,9 @@ PHP_MINIT_FUNCTION(date) REGISTER_STRING_CONSTANT("DATE_RSS", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_W3C", DATE_FORMAT_ISO8601, CONST_CS | CONST_PERSISTENT); + php_date_global_timezone_db = NULL; + php_date_global_timezone_db_enabled = 0; + return SUCCESS; } /* }}} */ @@ -246,8 +255,12 @@ PHP_MSHUTDOWN_FUNCTION(date) /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(date) { + timelib_tzdb *tzdb = DATE_TIMEZONEDB; + php_info_print_table_start(); php_info_print_table_row(2, "date/time support", "enabled"); + php_info_print_table_row(2, "Timezone Database Version", tzdb->version); + php_info_print_table_row(2, "Timezone Database", php_date_global_timezone_db_enabled ? "external" : "internal"); php_info_print_table_row(2, "Default timezone", guess_timezone(TSRMLS_C)); php_info_print_table_end(); @@ -302,10 +315,10 @@ static timelib_tzinfo *get_timezone_info(TSRMLS_D) timelib_tzinfo *tzi; tz = guess_timezone(TSRMLS_C); - tzi = timelib_parse_tzfile(tz); + tzi = timelib_parse_tzfile(tz, DATE_TIMEZONEDB); if (! tzi) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Timezone setting (date.timezone) or TZ environment variable contains an unknown timezone."); - tzi = timelib_parse_tzfile("UTC"); + tzi = timelib_parse_tzfile("UTC", DATE_TIMEZONEDB); if (! tzi) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Timezone database is corrupt - this should *never* happen!"); @@ -649,6 +662,13 @@ PHP_FUNCTION(gmdate) } /* }}} */ +/* {{{ php_date_set_tzdb - NOT THREADSAFE */ +PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb) +{ + php_date_global_timezone_db = tzdb; + php_date_global_timezone_db_enabled = 1; +} +/* }}} */ /* {{{ php_parse_date: Backwards compability function */ signed long php_parse_date(char *string, signed long *now) @@ -657,7 +677,7 @@ signed long php_parse_date(char *string, signed long *now) int error1, error2; signed long retval; - parsed_time = timelib_strtotime(string, &error1); + parsed_time = timelib_strtotime(string, &error1, DATE_TIMEZONEDB); timelib_update_ts(parsed_time, NULL); retval = timelib_date_to_int(parsed_time, &error2); timelib_time_dtor(parsed_time); @@ -688,7 +708,7 @@ PHP_FUNCTION(strtotime) initial_ts = emalloc(25); snprintf(initial_ts, 24, "@%lu", preset_ts); - t = timelib_strtotime(initial_ts, &error1); /* we ignore the error here, as this should never fail */ + t = timelib_strtotime(initial_ts, &error1, DATE_TIMEZONEDB); /* we ignore the error here, as this should never fail */ timelib_update_ts(t, tzi); timelib_unixtime2local(now, t->sse, tzi); timelib_time_dtor(t); @@ -702,7 +722,7 @@ PHP_FUNCTION(strtotime) RETURN_FALSE; } - t = timelib_strtotime(times, &error1); + t = timelib_strtotime(times, &error1, DATE_TIMEZONEDB); timelib_fill_holes(t, now, 0); timelib_update_ts(t, tzi); ts = timelib_date_to_int(t, &error2); @@ -1147,7 +1167,7 @@ PHP_FUNCTION(date_create) date_instanciate(date_ce_date, return_value TSRMLS_CC); dateobj = (php_date_obj *) zend_object_store_get_object(return_value TSRMLS_CC); - dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", &error); + dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", &error, DATE_TIMEZONEDB); if (timezone_object) { php_timezone_obj *tzobj; @@ -1226,7 +1246,7 @@ PHP_FUNCTION(date_modify) } dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); - tmp_time = timelib_strtotime(modify, &error); + tmp_time = timelib_strtotime(modify, &error, DATE_TIMEZONEDB); dateobj->time->relative.y = tmp_time->relative.y; dateobj->time->relative.m = tmp_time->relative.m; dateobj->time->relative.d = tmp_time->relative.d; @@ -1369,12 +1389,12 @@ PHP_FUNCTION(timezone_open) tzid = timelib_timezone_id_from_abbr(tz, -1, 0); if (tzid) { - tzi = timelib_parse_tzfile(tzid); + tzi = timelib_parse_tzfile(tzid, DATE_TIMEZONEDB); } } /* Try finding the tz information as "Timezone Identifier" */ if (!tzi) { - tzi = timelib_parse_tzfile(tz); + tzi = timelib_parse_tzfile(tz, DATE_TIMEZONEDB); } /* If we find it we instantiate the object otherwise, well, we don't and return false */ if (tzi) { @@ -1444,10 +1464,13 @@ PHP_FUNCTION(timezone_transistions_get) PHP_FUNCTION(timezone_identifiers_list) { + timelib_tzdb *tzdb; timelib_tzdb_index_entry *table; int i, item_count; - - table = timelib_timezone_identifiers_list(&item_count); + + tzdb = DATE_TIMEZONEDB; + item_count = tzdb->index_size; + table = tzdb->index; array_init(return_value); @@ -1459,12 +1482,12 @@ PHP_FUNCTION(timezone_identifiers_list) PHP_FUNCTION(timezone_abbreviations_list) { timelib_tz_lookup_table *table, *entry; - zval *element; + zval *element, **abbr_array_pp, *abbr_array; table = timelib_timezone_abbreviations_list(); array_init(return_value); entry = table; -#warning NEED TO MAKE SURE ABBRS ARE NOT UNIQUEIZED HERE + do { MAKE_STD_ZVAL(element); array_init(element); @@ -1476,7 +1499,14 @@ PHP_FUNCTION(timezone_abbreviations_list) add_assoc_null(element, "timezone_id"); } - add_assoc_zval(return_value, entry->name, element); + if (zend_hash_find(HASH_OF(return_value), entry->name, strlen(entry->name) + 1, (void **) &abbr_array_pp) == FAILURE) { + MAKE_STD_ZVAL(abbr_array); + array_init(abbr_array); + add_assoc_zval(return_value, entry->name, abbr_array); + } else { + abbr_array = *abbr_array_pp; + } + add_next_index_zval(abbr_array, element); entry++; } while (entry->name); } diff --git a/ext/date/php_date.h b/ext/date/php_date.h index 028b79a0c3..c40c451bee 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -21,6 +21,8 @@ #ifndef PHP_DATE_H #define PHP_DATE_H +#include "lib/timelib.h" + extern zend_module_entry date_module_entry; #define phpext_date_ptr &date_module_entry @@ -94,4 +96,7 @@ PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gm); #endif PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localtime TSRMLS_DC); +/* Mechanism to set new TZ database */ +PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb); + #endif /* PHP_DATE_H */