summaryrefslogtreecommitdiff
path: root/ext/date/lib/parse_tz.c
diff options
context:
space:
mode:
authorDerick Rethans <derick@php.net>2008-07-18 14:33:53 +0000
committerDerick Rethans <derick@php.net>2008-07-18 14:33:53 +0000
commit84693147d0e05f32f44036a9bf3e49f6c7b48086 (patch)
tree075d2556ede6a1355d5dc83519c085b360a73a64 /ext/date/lib/parse_tz.c
parent039bc2d3e25b5f0dd50f3db4bed06c10b6077168 (diff)
downloadphp-git-84693147d0e05f32f44036a9bf3e49f6c7b48086.tar.gz
- MFH: Added support for selectively listing timezone identifiers by country
code through timezone_identifiers_list() / DateTimezone::listIdentifiers(). - MFH: Added timezone_location_get() / DateTimezone::getLocation() for retrieving location information from timezones.
Diffstat (limited to 'ext/date/lib/parse_tz.c')
-rw-r--r--ext/date/lib/parse_tz.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c
index f7999d111e..81d3481a02 100644
--- a/ext/date/lib/parse_tz.c
+++ b/ext/date/lib/parse_tz.c
@@ -49,6 +49,24 @@
#define timelib_conv_int(l) ((l & 0x000000ff) << 24) + ((l & 0x0000ff00) << 8) + ((l & 0x00ff0000) >> 8) + ((l & 0xff000000) >> 24)
#endif
+static void read_preamble(char **tzf, timelib_tzinfo *tz)
+{
+ /* skip ID */
+ *tzf += 4;
+
+ /* read BC flag */
+ tz->bc = (**tzf == '\1');
+ *tzf += 1;
+
+ /* read country code */
+ memcpy(tz->location.country_code, *tzf, 2);
+ tz->location.country_code[2] = '\0';
+ *tzf += 2;
+
+ /* skip read of preamble */
+ *tzf += 13;
+}
+
static void read_header(char **tzf, timelib_tzinfo *tz)
{
uint32_t buffer[6];
@@ -167,10 +185,33 @@ static void read_types(char **tzf, timelib_tzinfo *tz)
free(buffer);
}
+static void read_location(char **tzf, timelib_tzinfo *tz)
+{
+ uint32_t buffer[3];
+ uint32_t comments_len;
+
+ memcpy(&buffer, *tzf, sizeof(buffer));
+ tz->location.latitude = timelib_conv_int(buffer[0]);
+ tz->location.latitude = (tz->location.latitude / 100000) - 90;
+ tz->location.longitude = timelib_conv_int(buffer[1]);
+ tz->location.longitude = (tz->location.longitude / 100000) - 180;
+ comments_len = timelib_conv_int(buffer[2]);
+ *tzf += sizeof(buffer);
+
+ tz->location.comments = malloc(comments_len + 1);
+ memcpy(tz->location.comments, *tzf, comments_len);
+ tz->location.comments[comments_len] = '\0';
+ *tzf += comments_len;
+}
+
void timelib_dump_tzinfo(timelib_tzinfo *tz)
{
uint32_t i;
+ printf("Country Code: %s\n", tz->location.country_code);
+ printf("Geo Location: %f,%f\n", tz->location.latitude, tz->location.longitude);
+ printf("Comments:\n%s\n", tz->location.comments);
+ printf("BC: %s\n", tz->bc ? "" : "yes");
printf("UTC/Local count: %lu\n", (unsigned long) tz->ttisgmtcnt);
printf("Std/Wall count: %lu\n", (unsigned long) tz->ttisstdcnt);
printf("Leap.sec. count: %lu\n", (unsigned long) tz->leapcnt);
@@ -228,7 +269,7 @@ static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const
} else if (cmp > 0) {
left = mid + 1;
} else { /* (cmp == 0) */
- (*tzf) = &(tzdb->data[tzdb->index[mid].pos + 20]);
+ (*tzf) = &(tzdb->data[tzdb->index[mid].pos]);
#ifdef HAVE_SETLOCALE
setlocale(LC_CTYPE, cur_locale);
if (cur_locale) free(cur_locale);
@@ -270,9 +311,11 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb)
if (seek_to_tz_position(&tzf, timezone, tzdb)) {
tmp = timelib_tzinfo_ctor(timezone);
+ read_preamble((char**) &tzf, tmp);
read_header((char**) &tzf, tmp);
read_transistions((char**) &tzf, tmp);
read_types((char**) &tzf, tmp);
+ read_location((char**) &tzf, tmp);
} else {
tmp = NULL;
}