derick Fri Jul 18 14:33:27 2008 UTC Modified files: /php-src/ext/date php_date.c php_date.h /php-src/ext/date/lib parse_tz.c timelib_structs.h Log: - Added support for selectively listing timezone identifiers by country code through timezone_identifiers_list() / DateTimezone::listIdentifiers(). - Added timezone_location_get() / DateTimezone::getLocation() for retrieving location information from timezones.
http://cvs.php.net/viewvc.cgi/php-src/ext/date/php_date.c?r1=1.196&r2=1.197&diff_format=u Index: php-src/ext/date/php_date.c diff -u php-src/ext/date/php_date.c:1.196 php-src/ext/date/php_date.c:1.197 --- php-src/ext/date/php_date.c:1.196 Wed Jul 16 12:35:45 2008 +++ php-src/ext/date/php_date.c Fri Jul 18 14:33:27 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_date.c,v 1.196 2008/07/16 12:35:45 derick Exp $ */ +/* $Id: php_date.c,v 1.197 2008/07/18 14:33:27 derick Exp $ */ #include "php.h" #include "php_streams.h" @@ -372,6 +372,15 @@ ZEND_END_ARG_INFO() static +ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_location_get, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_timezone_method_location_get, 0) +ZEND_END_ARG_INFO() + +static ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_identifiers_list, 0, 0, 0) ZEND_ARG_INFO(0, what) ZEND_END_ARG_INFO() @@ -459,6 +468,7 @@ PHP_FE(timezone_name_from_abbr, arginfo_timezone_name_from_abbr) PHP_FE(timezone_offset_get, arginfo_timezone_offset_get) PHP_FE(timezone_transitions_get, arginfo_timezone_transitions_get) + PHP_FE(timezone_location_get, arginfo_timezone_location_get) PHP_FE(timezone_identifiers_list, arginfo_timezone_identifiers_list) PHP_FE(timezone_abbreviations_list, arginfo_timezone_abbreviations_list) @@ -503,6 +513,7 @@ PHP_ME_MAPPING(getName, timezone_name_get, arginfo_timezone_method_name_get, 0) PHP_ME_MAPPING(getOffset, timezone_offset_get, arginfo_timezone_method_offset_get, 0) PHP_ME_MAPPING(getTransitions, timezone_transitions_get, arginfo_timezone_method_transitions_get, 0) + PHP_ME_MAPPING(getLocation, timezone_location_get, arginfo_timezone_method_location_get, 0) PHP_ME_MAPPING(listAbbreviations, timezone_abbreviations_list, arginfo_timezone_abbreviations_list, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME_MAPPING(listIdentifiers, timezone_identifiers_list, arginfo_timezone_identifiers_list, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) {NULL, NULL, NULL} @@ -1955,6 +1966,7 @@ #define PHP_DATE_TIMEZONE_GROUP_UTC 0x0400 #define PHP_DATE_TIMEZONE_GROUP_ALL 0x07FF #define PHP_DATE_TIMEZONE_GROUP_ALL_W_BC 0x0FFF +#define PHP_DATE_TIMEZONE_PER_COUNTRY 0x1000 #define PHP_DATE_PERIOD_EXCLUDE_START_DATE 0x0001 @@ -2157,6 +2169,7 @@ REGISTER_TIMEZONE_CLASS_CONST_STRING("UTC", PHP_DATE_TIMEZONE_GROUP_UTC); REGISTER_TIMEZONE_CLASS_CONST_STRING("ALL", PHP_DATE_TIMEZONE_GROUP_ALL); REGISTER_TIMEZONE_CLASS_CONST_STRING("ALL_WITH_BC", PHP_DATE_TIMEZONE_GROUP_ALL_W_BC); + REGISTER_TIMEZONE_CLASS_CONST_STRING("PER_COUNTRY", PHP_DATE_TIMEZONE_PER_COUNTRY); INIT_CLASS_ENTRY(ce_interval, "DateInterval", date_funcs_interval); ce_interval.create_object = date_object_new_interval; @@ -3531,6 +3544,31 @@ } /* }}} */ +/* {{{ proto array timezone_location_get() + Returns location information for a timezone, including country code, latitude/longitude and comments +*/ +PHP_FUNCTION(timezone_location_get) +{ + zval *object; + php_timezone_obj *tzobj; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_timezone) == FAILURE) { + RETURN_FALSE; + } + tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC); + DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone); + if (tzobj->type != TIMELIB_ZONETYPE_ID) { + RETURN_FALSE; + } + + array_init(return_value); + add_assoc_string(return_value, "country_code", tzobj->tzi.tz->location.country_code, 1); + add_assoc_double(return_value, "latitude", tzobj->tzi.tz->location.latitude); + add_assoc_double(return_value, "longitude", tzobj->tzi.tz->location.longitude); + add_assoc_string(return_value, "comments", tzobj->tzi.tz->location.comments, 1); +} +/* }}} */ + static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *format, int format_length TSRMLS_DC) { timelib_time *b = NULL, *e = NULL; @@ -3909,8 +3947,16 @@ const timelib_tzdb_index_entry *table; int i, item_count; long what = PHP_DATE_TIMEZONE_GROUP_ALL; + char *option; + int option_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &what) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &what, &option, &option_len) == FAILURE) { + RETURN_FALSE; + } + + /* Extra validation */ + if (what == PHP_DATE_TIMEZONE_PER_COUNTRY && option_len != 2) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "A two-letter ISO 639-2 compatible country code is expected"); RETURN_FALSE; } @@ -3921,7 +3967,11 @@ array_init(return_value); for (i = 0; i < item_count; ++i) { - if (what == PHP_DATE_TIMEZONE_GROUP_ALL_W_BC || check_id_allowed(table[i].id, what)) { + if (what == PHP_DATE_TIMEZONE_PER_COUNTRY) { + if (tzdb->data[table[i].pos + 5] == option[0] && tzdb->data[table[i].pos + 6] == option[1]) { + add_next_index_ascii_string(return_value, table[i].id, 1); + } + } else if (what == PHP_DATE_TIMEZONE_GROUP_ALL_W_BC || (check_id_allowed(table[i].id, what) && (tzdb->data[table[i].pos + 4] == '\1'))) { add_next_index_ascii_string(return_value, table[i].id, 1); } }; http://cvs.php.net/viewvc.cgi/php-src/ext/date/php_date.h?r1=1.40&r2=1.41&diff_format=u Index: php-src/ext/date/php_date.h diff -u php-src/ext/date/php_date.h:1.40 php-src/ext/date/php_date.h:1.41 --- php-src/ext/date/php_date.h:1.40 Fri May 2 12:48:19 2008 +++ php-src/ext/date/php_date.h Fri Jul 18 14:33:27 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_date.h,v 1.40 2008/05/02 12:48:19 derick Exp $ */ +/* $Id: php_date.h,v 1.41 2008/07/18 14:33:27 derick Exp $ */ #ifndef PHP_DATE_H #define PHP_DATE_H @@ -77,6 +77,7 @@ PHP_FUNCTION(timezone_name_from_abbr); PHP_FUNCTION(timezone_offset_get); PHP_FUNCTION(timezone_transitions_get); +PHP_FUNCTION(timezone_location_get); PHP_FUNCTION(timezone_identifiers_list); PHP_FUNCTION(timezone_abbreviations_list); http://cvs.php.net/viewvc.cgi/php-src/ext/date/lib/parse_tz.c?r1=1.36&r2=1.37&diff_format=u Index: php-src/ext/date/lib/parse_tz.c diff -u php-src/ext/date/lib/parse_tz.c:1.36 php-src/ext/date/lib/parse_tz.c:1.37 --- php-src/ext/date/lib/parse_tz.c:1.36 Mon Apr 7 17:43:49 2008 +++ php-src/ext/date/lib/parse_tz.c Fri Jul 18 14:33:27 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: parse_tz.c,v 1.36 2008/04/07 17:43:49 derick Exp $ */ +/* $Id: parse_tz.c,v 1.37 2008/07/18 14:33:27 derick Exp $ */ #include "timelib.h" @@ -45,6 +45,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]; @@ -163,10 +181,33 @@ 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); @@ -215,7 +256,7 @@ } 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]); return 1; } @@ -249,9 +290,11 @@ 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; } http://cvs.php.net/viewvc.cgi/php-src/ext/date/lib/timelib_structs.h?r1=1.28&r2=1.29&diff_format=u Index: php-src/ext/date/lib/timelib_structs.h diff -u php-src/ext/date/lib/timelib_structs.h:1.28 php-src/ext/date/lib/timelib_structs.h:1.29 --- php-src/ext/date/lib/timelib_structs.h:1.28 Thu May 1 16:14:29 2008 +++ php-src/ext/date/lib/timelib_structs.h Fri Jul 18 14:33:27 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: timelib_structs.h,v 1.28 2008/05/01 16:14:29 derick Exp $ */ +/* $Id: timelib_structs.h,v 1.29 2008/07/18 14:33:27 derick Exp $ */ #ifndef __TIMELIB_STRUCTS_H__ #define __TIMELIB_STRUCTS_H__ @@ -97,6 +97,14 @@ int32_t offset; } tlinfo; +typedef struct tlocinfo +{ + char country_code[3]; + double latitude; + double longitude; + char *comments; +} tlocinfo; + typedef struct timelib_tzinfo { char *name; @@ -114,6 +122,8 @@ char *timezone_abbr; tlinfo *leap_times; + unsigned char bc; + tlocinfo location; } timelib_tzinfo; typedef struct timelib_special {
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php