From d67639643598781d70452f690a645dc8ce6bd3c3 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Wed, 5 Feb 2014 21:00:13 -0500 Subject: [PATCH] Implemented feature #45528: Allow the DateTimeZone constructor to accept timezones per offset too. --- ext/date/php_date.c | 112 +++++++----------- ext/date/tests/DateTimeZone_clone_basic1.phpt | 8 +- .../tests/DateTimeZone_construct_basic.phpt | 4 +- .../DateTimeZone_construct_variation1.phpt | 8 -- .../tests/DateTimeZone_serialize_type_2.phpt | 12 +- .../tests/DateTimeZone_serialize_type_3.phpt | 4 +- ext/date/tests/timezone_open_basic1.phpt | 6 +- ext/date/tests/timezone_open_variation1.phpt | 12 -- 8 files changed, 57 insertions(+), 109 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 0e21baffa6..a61d9db3c1 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2297,7 +2297,7 @@ static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC) case TIMELIB_ZONETYPE_ABBR: new_obj->tzi.z.utc_offset = old_obj->tzi.z.utc_offset; new_obj->tzi.z.dst = old_obj->tzi.z.dst; - new_obj->tzi.z.abbr = old_obj->tzi.z.abbr; + new_obj->tzi.z.abbr = strdup(old_obj->tzi.z.abbr); break; } @@ -3238,6 +3238,26 @@ PHP_METHOD(DateTimeImmutable, sub) } /* }}} */ +static void set_timezone_from_timelib_time(php_timezone_obj *tzobj, timelib_time *t) +{ + tzobj->initialized = 1; + tzobj->type = t->zone_type; + switch (t->zone_type) { + case TIMELIB_ZONETYPE_ID: + tzobj->tzi.tz = t->tz_info; + break; + case TIMELIB_ZONETYPE_OFFSET: + tzobj->tzi.utc_offset = t->z; + break; + case TIMELIB_ZONETYPE_ABBR: + tzobj->tzi.z.utc_offset = t->z; + tzobj->tzi.z.dst = t->dst; + tzobj->tzi.z.abbr = strdup(t->tz_abbr); + break; + } +} + + /* {{{ proto DateTimeZone date_timezone_get(DateTimeInterface object) Return new DateTimeZone object relative to give DateTime */ @@ -3255,21 +3275,7 @@ PHP_FUNCTION(date_timezone_get) if (dateobj->time->is_localtime/* && dateobj->time->tz_info*/) { php_date_instantiate(date_ce_timezone, return_value TSRMLS_CC); tzobj = (php_timezone_obj *) zend_object_store_get_object(return_value TSRMLS_CC); - tzobj->initialized = 1; - tzobj->type = dateobj->time->zone_type; - switch (dateobj->time->zone_type) { - case TIMELIB_ZONETYPE_ID: - tzobj->tzi.tz = dateobj->time->tz_info; - break; - case TIMELIB_ZONETYPE_OFFSET: - tzobj->tzi.utc_offset = dateobj->time->z; - break; - case TIMELIB_ZONETYPE_ABBR: - tzobj->tzi.z.utc_offset = dateobj->time->z; - tzobj->tzi.z.dst = dateobj->time->dst; - tzobj->tzi.z.abbr = strdup(dateobj->time->tz_abbr); - break; - } + set_timezone_from_timelib_time(tzobj, dateobj->time); } else { RETURN_FALSE; } @@ -3620,23 +3626,21 @@ PHP_FUNCTION(date_diff) } /* }}} */ -static int timezone_initialize(timelib_tzinfo **tzi, /*const*/ char *tz TSRMLS_DC) +static int timezone_initialize(php_timezone_obj *tzobj, /*const*/ char *tz TSRMLS_DC) { - char *tzid; - - *tzi = NULL; - - if ((tzid = timelib_timezone_id_from_abbr(tz, -1, 0))) { - *tzi = php_date_parse_tzfile(tzid, DATE_TIMEZONEDB TSRMLS_CC); + timelib_time *dummy_t = ecalloc(1, sizeof(timelib_time)); + int dst, not_found; + char *orig_tz = tz; + + dummy_t->z = timelib_parse_zone(&tz, &dst, dummy_t, ¬_found, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + if (not_found) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad timezone (%s)", orig_tz); + efree(dummy_t); + return FAILURE; } else { - *tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB TSRMLS_CC); - } - - if (*tzi) { + set_timezone_from_timelib_time(tzobj, dummy_t TSRMLS_CC); + efree(dummy_t); return SUCCESS; - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad timezone (%s)", tz); - return FAILURE; } } @@ -3647,19 +3651,15 @@ PHP_FUNCTION(timezone_open) { char *tz; int tz_len; - timelib_tzinfo *tzi = NULL; php_timezone_obj *tzobj; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len) == FAILURE) { RETURN_FALSE; } - if (SUCCESS != timezone_initialize(&tzi, tz TSRMLS_CC)) { + tzobj = zend_object_store_get_object(php_date_instantiate(date_ce_timezone, return_value TSRMLS_CC) TSRMLS_CC); + if (SUCCESS != timezone_initialize(tzobj, tz TSRMLS_CC)) { RETURN_FALSE; } - tzobj = zend_object_store_get_object(php_date_instantiate(date_ce_timezone, return_value TSRMLS_CC) TSRMLS_CC); - tzobj->type = TIMELIB_ZONETYPE_ID; - tzobj->tzi.tz = tzi; - tzobj->initialized = 1; } /* }}} */ @@ -3670,18 +3670,13 @@ PHP_METHOD(DateTimeZone, __construct) { char *tz; int tz_len; - timelib_tzinfo *tzi = NULL; php_timezone_obj *tzobj; zend_error_handling error_handling; zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len)) { - if (SUCCESS == timezone_initialize(&tzi, tz TSRMLS_CC)) { - tzobj = zend_object_store_get_object(getThis() TSRMLS_CC); - tzobj->type = TIMELIB_ZONETYPE_ID; - tzobj->tzi.tz = tzi; - tzobj->initialized = 1; - } else { + tzobj = zend_object_store_get_object(getThis() TSRMLS_CC); + if (FAILURE == timezone_initialize(tzobj, tz TSRMLS_CC)) { ZVAL_NULL(getThis()); } } @@ -3693,39 +3688,12 @@ static int php_date_timezone_initialize_from_hash(zval **return_value, php_timez { zval **z_timezone = NULL; zval **z_timezone_type = NULL; - timelib_tzinfo *tzi; if (zend_hash_find(myht, "timezone_type", 14, (void**) &z_timezone_type) == SUCCESS) { if (zend_hash_find(myht, "timezone", 9, (void**) &z_timezone) == SUCCESS) { convert_to_long(*z_timezone_type); - switch (Z_LVAL_PP(z_timezone_type)) { - case TIMELIB_ZONETYPE_OFFSET: { - char *offset, *offset_start; - - offset = emalloc(sizeof(char) * (Z_STRLEN_PP(z_timezone) + 1)); - memmove(offset, Z_STRVAL_PP(z_timezone), Z_STRLEN_PP(z_timezone)+1); - offset_start = offset; - - ++offset; - if(*offset_start == '+'){ - (*tzobj)->tzi.utc_offset = -1 * timelib_parse_tz_cor(&offset); - } else { - (*tzobj)->tzi.utc_offset = timelib_parse_tz_cor(&offset); - } - efree(offset_start); - (*tzobj)->type = TIMELIB_ZONETYPE_OFFSET; - (*tzobj)->initialized = 1; - return SUCCESS; - break; - } - case TIMELIB_ZONETYPE_ABBR: - case TIMELIB_ZONETYPE_ID: - if (SUCCESS == timezone_initialize(&tzi, Z_STRVAL_PP(z_timezone) TSRMLS_CC)) { - (*tzobj)->type = TIMELIB_ZONETYPE_ID; - (*tzobj)->tzi.tz = tzi; - (*tzobj)->initialized = 1; - return SUCCESS; - } + if (SUCCESS == timezone_initialize(*tzobj, Z_STRVAL_PP(z_timezone) TSRMLS_CC)) { + return SUCCESS; } } } diff --git a/ext/date/tests/DateTimeZone_clone_basic1.phpt b/ext/date/tests/DateTimeZone_clone_basic1.phpt index a89005aaec..49c190cf9f 100644 --- a/ext/date/tests/DateTimeZone_clone_basic1.phpt +++ b/ext/date/tests/DateTimeZone_clone_basic1.phpt @@ -31,15 +31,15 @@ if ($clone != $orig) { *** Testing clone on DateTime objects *** object(DateTimeZone)#%d (2) { ["timezone_type"]=> - int(3) + int(2) ["timezone"]=> - string(3) "UTC" + string(3) "GMT" } object(DateTimeZone)#%d (2) { ["timezone_type"]=> - int(3) + int(2) ["timezone"]=> - string(3) "UTC" + string(3) "GMT" } TEST PASSED : Objects equal but not indetical ===DONE=== diff --git a/ext/date/tests/DateTimeZone_construct_basic.phpt b/ext/date/tests/DateTimeZone_construct_basic.phpt index 2f18f81c03..12b1090661 100644 --- a/ext/date/tests/DateTimeZone_construct_basic.phpt +++ b/ext/date/tests/DateTimeZone_construct_basic.phpt @@ -23,9 +23,9 @@ var_dump( new DateTimeZone("America/Los_Angeles") ); *** Testing new DateTimeZone() : basic functionality *** object(DateTimeZone)#%d (2) { ["timezone_type"]=> - int(3) + int(2) ["timezone"]=> - string(3) "UTC" + string(3) "GMT" } object(DateTimeZone)#%d (2) { ["timezone_type"]=> diff --git a/ext/date/tests/DateTimeZone_construct_variation1.phpt b/ext/date/tests/DateTimeZone_construct_variation1.phpt index 65e575ee44..025c6e2678 100644 --- a/ext/date/tests/DateTimeZone_construct_variation1.phpt +++ b/ext/date/tests/DateTimeZone_construct_variation1.phpt @@ -48,11 +48,9 @@ $inputs = array( 'int 0' => 0, 'int 1' => 1, 'int 12345' => 12345, - 'int -12345' => -12345, // float data 'float 10.5' => 10.5, - 'float -10.5' => -10.5, 'float .5' => .5, // array data @@ -123,15 +121,9 @@ FAILED: DateTimeZone::__construct(): Unknown or bad timezone (1) -- int 12345 -- FAILED: DateTimeZone::__construct(): Unknown or bad timezone (12345) --- int -12345 -- -FAILED: DateTimeZone::__construct(): Unknown or bad timezone (-12345) - -- float 10.5 -- FAILED: DateTimeZone::__construct(): Unknown or bad timezone (10.5) --- float -10.5 -- -FAILED: DateTimeZone::__construct(): Unknown or bad timezone (-10.5) - -- float .5 -- FAILED: DateTimeZone::__construct(): Unknown or bad timezone (0.5) diff --git a/ext/date/tests/DateTimeZone_serialize_type_2.phpt b/ext/date/tests/DateTimeZone_serialize_type_2.phpt index a264322f3e..4147efe927 100644 --- a/ext/date/tests/DateTimeZone_serialize_type_2.phpt +++ b/ext/date/tests/DateTimeZone_serialize_type_2.phpt @@ -20,16 +20,16 @@ var_dump( $tz2->getName() ); --EXPECTF-- object(DateTimeZone)#%d (2) { ["timezone_type"]=> - int(3) + int(2) ["timezone"]=> - string(16) "America/New_York" + string(3) "EST" } -string(88) "O:12:"DateTimeZone":2:{s:13:"timezone_type";i:3;s:8:"timezone";s:16:"America/New_York";}" +string(74) "O:12:"DateTimeZone":2:{s:13:"timezone_type";i:2;s:8:"timezone";s:3:"EST";}" object(DateTimeZone)#%d (2) { ["timezone_type"]=> - int(3) + int(2) ["timezone"]=> - string(16) "America/New_York" + string(3) "EST" } -string(16) "America/New_York" +string(3) "EST" ===DONE=== diff --git a/ext/date/tests/DateTimeZone_serialize_type_3.phpt b/ext/date/tests/DateTimeZone_serialize_type_3.phpt index 49b9349bb8..396bff9196 100644 --- a/ext/date/tests/DateTimeZone_serialize_type_3.phpt +++ b/ext/date/tests/DateTimeZone_serialize_type_3.phpt @@ -18,14 +18,14 @@ var_dump( $tz2->getName() ); ?> ===DONE=== --EXPECTF-- -object(DateTimeZone)#%d (2) { +object(DateTimeZone)#1 (2) { ["timezone_type"]=> int(3) ["timezone"]=> string(16) "America/New_York" } string(88) "O:12:"DateTimeZone":2:{s:13:"timezone_type";i:3;s:8:"timezone";s:16:"America/New_York";}" -object(DateTimeZone)#%d (2) { +object(DateTimeZone)#2 (2) { ["timezone_type"]=> int(3) ["timezone"]=> diff --git a/ext/date/tests/timezone_open_basic1.phpt b/ext/date/tests/timezone_open_basic1.phpt index 7fcfcb34cb..abd016b35a 100644 --- a/ext/date/tests/timezone_open_basic1.phpt +++ b/ext/date/tests/timezone_open_basic1.phpt @@ -20,9 +20,9 @@ var_dump( timezone_open("America/Los_Angeles") ); *** Testing timezone_open() : basic functionality *** object(DateTimeZone)#%d (2) { ["timezone_type"]=> - int(3) + int(2) ["timezone"]=> - string(3) "UTC" + string(3) "GMT" } object(DateTimeZone)#%d (2) { ["timezone_type"]=> @@ -36,4 +36,4 @@ object(DateTimeZone)#%d (2) { ["timezone"]=> string(19) "America/Los_Angeles" } -===DONE=== \ No newline at end of file +===DONE=== diff --git a/ext/date/tests/timezone_open_variation1.phpt b/ext/date/tests/timezone_open_variation1.phpt index 9a069f6472..eb4d4b782e 100644 --- a/ext/date/tests/timezone_open_variation1.phpt +++ b/ext/date/tests/timezone_open_variation1.phpt @@ -48,11 +48,9 @@ $inputs = array( 'int 0' => 0, 'int 1' => 1, 'int 12345' => 12345, - 'int -12345' => -12345, // float data 'float 10.5' => 10.5, - 'float -10.5' => -10.5, 'float .5' => .5, // array data @@ -124,21 +122,11 @@ bool(false) Warning: timezone_open(): Unknown or bad timezone (12345) in %s on line %d bool(false) --- int -12345 -- - -Warning: timezone_open(): Unknown or bad timezone (-12345) in %s on line %d -bool(false) - -- float 10.5 -- Warning: timezone_open(): Unknown or bad timezone (10.5) in %s on line %d bool(false) --- float -10.5 -- - -Warning: timezone_open(): Unknown or bad timezone (-10.5) in %s on line %d -bool(false) - -- float .5 -- Warning: timezone_open(): Unknown or bad timezone (0.5) in %s on line %d -- 2.40.0