diff options
author | Derick Rethans <github@derickrethans.nl> | 2014-01-26 14:02:44 +0100 |
---|---|---|
committer | Derick Rethans <github@derickrethans.nl> | 2014-01-26 14:02:44 +0100 |
commit | 2e65908643a22c0ffabf604bd948912eb7b95226 (patch) | |
tree | 26010ccb59aa896ca97eb80b07525fcc2356c7b1 | |
parent | 6d6850b3b8521364f0950242c49ab774cfd97dce (diff) | |
parent | 7399386a2094ccce9b5deb0c035ff6ac2aa7eb8b (diff) | |
download | php-git-2e65908643a22c0ffabf604bd948912eb7b95226.tar.gz |
Merge branch 'PHP-5.5' into PHP-5.6
-rw-r--r-- | ext/date/lib/timelib.h | 2 | ||||
-rw-r--r-- | ext/date/lib/timelib_structs.h | 6 | ||||
-rw-r--r-- | ext/date/lib/unixtime2tm.c | 28 | ||||
-rw-r--r-- | ext/date/php_date.c | 15 | ||||
-rw-r--r-- | ext/date/php_date.h | 11 | ||||
-rw-r--r-- | ext/date/tests/bug45543.phpt | 34 |
6 files changed, 84 insertions, 12 deletions
diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index f5e7597835..866eaf3dd2 100644 --- a/ext/date/lib/timelib.h +++ b/ext/date/lib/timelib.h @@ -92,6 +92,8 @@ int timelib_apply_localtime(timelib_time *t, unsigned int localtime); void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts); void timelib_unixtime2local(timelib_time *tm, timelib_sll ts); void timelib_update_from_sse(timelib_time *tm); +void timelib_set_timezone_from_offset(timelib_time *t, timelib_sll utc_offset); +void timelib_set_timezone_from_abbr(timelib_time *t, timelib_abbr_info abbr_info); void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz); /* From parse_tz.c */ diff --git a/ext/date/lib/timelib_structs.h b/ext/date/lib/timelib_structs.h index de75545c48..5033321356 100644 --- a/ext/date/lib/timelib_structs.h +++ b/ext/date/lib/timelib_structs.h @@ -142,6 +142,12 @@ typedef struct timelib_time { * 2 TimeZone abbreviation */ } timelib_time; +typedef struct timelib_abbr_info { + timelib_sll utc_offset; + char *abbr; + int dst; +} timelib_abbr_info; + typedef struct timelib_error_message { int position; char character; diff --git a/ext/date/lib/unixtime2tm.c b/ext/date/lib/unixtime2tm.c index eefbaa8f37..9870313fbc 100644 --- a/ext/date/lib/unixtime2tm.c +++ b/ext/date/lib/unixtime2tm.c @@ -214,6 +214,34 @@ void timelib_unixtime2local(timelib_time *tm, timelib_sll ts) tm->have_zone = 1; } +void timelib_set_timezone_from_offset(timelib_time *t, timelib_sll utc_offset) +{ + if (t->tz_abbr) { + free(t->tz_abbr); + } + t->tz_abbr = NULL; + + t->z = utc_offset; + t->have_zone = 1; + t->zone_type = TIMELIB_ZONETYPE_OFFSET; + t->dst = 0; + t->tz_info = NULL; +} + +void timelib_set_timezone_from_abbr(timelib_time *t, timelib_abbr_info abbr_info) +{ + if (t->tz_abbr) { + free(t->tz_abbr); + } + t->tz_abbr = strdup(abbr_info.abbr); + + t->z = abbr_info.utc_offset; + t->have_zone = 1; + t->zone_type = TIMELIB_ZONETYPE_ABBR; + t->dst = abbr_info.dst; + t->tz_info = NULL; +} + void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz) { timelib_time_offset *gmt_offset; diff --git a/ext/date/php_date.c b/ext/date/php_date.c index c069e0ccae..0e21baffa6 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -3284,11 +3284,18 @@ static void php_date_timezone_set(zval *object, zval *timezone_object, zval *ret dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); DATE_CHECK_INITIALIZED(dateobj->time, DateTime); tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC); - if (tzobj->type != TIMELIB_ZONETYPE_ID) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only do this for zones with ID for now"); - return; + + switch (tzobj->type) { + case TIMELIB_ZONETYPE_OFFSET: + timelib_set_timezone_from_offset(dateobj->time, tzobj->tzi.utc_offset); + break; + case TIMELIB_ZONETYPE_ABBR: + timelib_set_timezone_from_abbr(dateobj->time, tzobj->tzi.z); + break; + case TIMELIB_ZONETYPE_ID: + timelib_set_timezone(dateobj->time, tzobj->tzi.tz); + break; } - timelib_set_timezone(dateobj->time, tzobj->tzi.tz); timelib_unixtime2local(dateobj->time, dateobj->time->sse); } diff --git a/ext/date/php_date.h b/ext/date/php_date.h index d4204ebd79..d7343e02bc 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -137,14 +137,9 @@ struct _php_timezone_obj { int initialized; int type; union { - timelib_tzinfo *tz; /* TIMELIB_ZONETYPE_ID; */ - timelib_sll utc_offset; /* TIMELIB_ZONETYPE_OFFSET */ - struct /* TIMELIB_ZONETYPE_ABBR */ - { - timelib_sll utc_offset; - char *abbr; - int dst; - } z; + timelib_tzinfo *tz; /* TIMELIB_ZONETYPE_ID */ + timelib_sll utc_offset; /* TIMELIB_ZONETYPE_OFFSET */ + timelib_abbr_info z; /* TIMELIB_ZONETYPE_ABBR */ } tzi; HashTable *props; }; diff --git a/ext/date/tests/bug45543.phpt b/ext/date/tests/bug45543.phpt new file mode 100644 index 0000000000..8e36e6287c --- /dev/null +++ b/ext/date/tests/bug45543.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test for bug #45543: DateTime::setTimezone can not set timezones without ID. +--INI-- +date.timezone=UTC +--FILE-- +<?php +$test_dates = array( + '2008-01-01 12:00:00 PDT', + '2008-01-01 12:00:00 +02:00', +); + +foreach ($test_dates as $test_date) +{ + $d1 = new DateTime($test_date); + $d2 = new DateTime('2008-01-01 12:00:00 UTC'); + echo $d1->format(DATE_ISO8601), PHP_EOL; + echo $d2->format(DATE_ISO8601), PHP_EOL; + $tz = $d1->getTimeZone(); + $d2->setTimeZone($tz); + echo $d1->format(DATE_ISO8601), PHP_EOL; + echo $d2->format(DATE_ISO8601), PHP_EOL; + echo PHP_EOL; +} +--EXPECT-- +2008-01-01T12:00:00-0700 +2008-01-01T12:00:00+0000 +2008-01-01T12:00:00-0700 +2008-01-01T05:00:00-0700 + +2008-01-01T12:00:00+0200 +2008-01-01T12:00:00+0000 +2008-01-01T12:00:00+0200 +2008-01-01T14:00:00+0200 + |