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

Reply via email to