summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerick Rethans <derick@php.net>2008-01-17 18:49:45 +0000
committerDerick Rethans <derick@php.net>2008-01-17 18:49:45 +0000
commite549873c107aefabe0f0d4fe779ba1ebb61e529a (patch)
treedd21358c26829d79719c378e75069fe39382c499
parentfd72cefbdae6acb3fe3ab00c4acb93644e887842 (diff)
downloadphp-git-e549873c107aefabe0f0d4fe779ba1ebb61e529a.tar.gz
- MFH: Added support for abbreviation and offset based timezone specifiers for
DateTime::getOffset() and DateTime::getName(). - MFH: Fixed bug #43527 (DateTime created from a timestamp reports environment timezone). - MFH: Fixed bug #42190 (Constructing DateTime with TimeZone Indicator invalidates DateTimeZone).
-rw-r--r--NEWS6
-rw-r--r--ext/date/lib/parse_date.c2
-rw-r--r--ext/date/php_date.c186
-rw-r--r--ext/date/tests/bug40743.phpt40
-rw-r--r--ext/date/tests/bug42910.phpt30
-rw-r--r--ext/date/tests/bug43527.phpt10
6 files changed, 243 insertions, 31 deletions
diff --git a/NEWS b/NEWS
index 74e9ec2fa3..3482130177 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ PHP NEWS
- strtotime() / new DateTime
- date_create_from_format() / DateTime::createFromFormat()
- date_parse_from_format()
+ * support for abbreviation and offset based timezone specifiers for
+ DateTime::getOffset() and DateTime::getName().
- Added ability to use Traversable objects instead of plain arrays in ext/soap.
(Joshua Reese, Dmitry)
@@ -75,6 +77,8 @@ PHP NEWS
- Fixed possible crash in ext/soap because of uninitialized value. (Zdash Urf)
+- Fixed bug #43527 (DateTime created from a timestamp reports environment
+ timezone). (Derick)
- Fixed bug #43143 (Warning about empty IV with MCRYPT_MODE_ECB). (Derick)
- Fixed bug #43136 (possible crash on script execution timeout.
The EG(function_state_ptr) is completely removed,
@@ -94,6 +98,8 @@ PHP NEWS
- Fixed bug #42548 (mysqli PROCEDURE calls can't return result sets). (hartmut)
- Fixed bug #42509 (gmp leaks memory when gmp_init() not used). (Stas)
- Fixed bug #42284 (duplicate of #39700). (Lars W)
+- Fixed bug #42190 (Constructing DateTime with TimeZone Indicator invalidates
+ DateTimeZone). (Derick)
- Fixed bug #42069 (parse_ini_file() allows using some non-alpha numeric
characters). (Jani)
- Fixed bug #41522 (PDO firebird driver returns null if it fails to connect).
diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c
index 244fe054d6..690888aa50 100644
--- a/ext/date/lib/parse_date.c
+++ b/ext/date/lib/parse_date.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.12.1 on Sun Jan 13 15:46:00 2008 */
+/* Generated by re2c 0.12.1 on Thu Jan 17 09:50:31 2008 */
#line 1 "ext/date/lib/parse_date.re"
/*
+----------------------------------------------------------------------+
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index 9fce43b470..08f8a6ffd6 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -273,7 +273,17 @@ struct _php_date_obj {
struct _php_timezone_obj {
zend_object std;
- timelib_tzinfo *tz;
+ 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;
+ } tzi;
};
#define DATE_SET_CONTEXT \
@@ -820,7 +830,26 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca
);
break;
case 'T': length = slprintf(buffer, 32, "%s", localtime ? offset->abbr : "GMT"); break;
- case 'e': length = slprintf(buffer, 32, "%s", localtime ? t->tz_info->name : "UTC"); break;
+ case 'e': if (!localtime) {
+ length = slprintf(buffer, 32, "%s", "UTC");
+ } else {
+ switch (t->zone_type) {
+ case TIMELIB_ZONETYPE_ID:
+ length = slprintf(buffer, 32, "%s", t->tz_info->name);
+ break;
+ case TIMELIB_ZONETYPE_ABBR:
+ length = slprintf(buffer, 32, "%s", offset->abbr);
+ break;
+ case TIMELIB_ZONETYPE_OFFSET:
+ length = slprintf(buffer, 32, "%c%02d:%02d",
+ ((offset->offset < 0) ? '-' : '+'),
+ abs(offset->offset / 3600),
+ abs((offset->offset % 3600) / 60)
+ );
+ break;
+ }
+ }
+ break;
case 'Z': length = slprintf(buffer, 32, "%d", localtime ? offset->offset : 0); break;
/* full date/time */
@@ -1098,7 +1127,7 @@ PHP_FUNCTION(strtotime)
now = timelib_time_ctor();
initial_ts = emalloc(25);
- snprintf(initial_ts, 24, "@%ld", preset_ts);
+ snprintf(initial_ts, 24, "@%ld UTC", preset_ts);
t = timelib_strtotime(initial_ts, strlen(initial_ts), NULL, DATE_TIMEZONEDB); /* we ignore the error here, as this should never fail */
timelib_update_ts(t, tzi);
now->tz_info = tzi;
@@ -1602,7 +1631,20 @@ static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC)
zend_object_value new_ov = date_object_new_timezone_ex(old_obj->std.ce, &new_obj TSRMLS_CC);
zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
- new_obj->tz = old_obj->tz;
+ new_obj->type = old_obj->type;
+ switch (new_obj->type) {
+ case TIMELIB_ZONETYPE_ID:
+ new_obj->tzi.tz = old_obj->tzi.tz;
+ break;
+ case TIMELIB_ZONETYPE_OFFSET:
+ new_obj->tzi.utc_offset = old_obj->tzi.utc_offset;
+ break;
+ 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;
+ break;
+ }
return new_ov;
}
@@ -1626,6 +1668,9 @@ static void date_object_free_storage_timezone(void *object TSRMLS_DC)
{
php_timezone_obj *intern = (php_timezone_obj *)object;
+ if (intern->type == TIMELIB_ZONETYPE_ABBR) {
+ free(intern->tzi.z.abbr);
+ }
zend_object_std_dtor(&intern->std TSRMLS_CC);
efree(object);
}
@@ -1660,7 +1705,9 @@ static void date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int
timelib_time *now;
timelib_tzinfo *tzi;
timelib_error_container *err = NULL;
- int free_tzi = 0;
+ int free_tzi = 0, type = TIMELIB_ZONETYPE_ID, new_dst;
+ char *new_abbr;
+ timelib_sll new_offset;
if (dateobj->time) {
if (dateobj->time->tz_info) {
@@ -1681,8 +1728,21 @@ static void date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int
php_timezone_obj *tzobj;
tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC);
- tzi = timelib_tzinfo_clone(tzobj->tz);
- free_tzi = 1;
+ switch (tzobj->type) {
+ case TIMELIB_ZONETYPE_ID:
+ tzi = timelib_tzinfo_clone(tzobj->tzi.tz);
+ free_tzi = 1;
+ break;
+ case TIMELIB_ZONETYPE_OFFSET:
+ new_offset = tzobj->tzi.utc_offset;
+ break;
+ case TIMELIB_ZONETYPE_ABBR:
+ new_offset = tzobj->tzi.z.utc_offset;
+ new_dst = tzobj->tzi.z.dst;
+ new_abbr = strdup(tzobj->tzi.z.abbr);
+ break;
+ }
+ type = tzobj->type;
} else if (dateobj->time->tz_info) {
tzi = timelib_tzinfo_clone(dateobj->time->tz_info);
free_tzi = 1;
@@ -1691,8 +1751,20 @@ static void date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int
}
now = timelib_time_ctor();
- now->tz_info = tzi;
- now->zone_type = TIMELIB_ZONETYPE_ID;
+ now->zone_type = type;
+ switch (type) {
+ case TIMELIB_ZONETYPE_ID:
+ now->tz_info = tzi;
+ break;
+ case TIMELIB_ZONETYPE_OFFSET:
+ now->z = new_offset;
+ break;
+ case TIMELIB_ZONETYPE_ABBR:
+ now->z = new_offset;
+ now->dst = new_dst;
+ now->tz_abbr = new_abbr;
+ break;
+ }
timelib_unixtime2local(now, (timelib_sll) time(NULL));
timelib_fill_holes(dateobj->time, now, 0);
@@ -1700,7 +1772,7 @@ static void date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int
dateobj->time->have_weekday_relative = dateobj->time->have_relative = 0;
- if (now->tz_info != tzi) {
+ if (type == TIMELIB_ZONETYPE_ID && now->tz_info != tzi) {
timelib_tzinfo_dtor(now->tz_info);
}
if (free_tzi) {
@@ -1977,10 +2049,23 @@ PHP_FUNCTION(date_timezone_get)
}
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
- if (dateobj->time->is_localtime && dateobj->time->tz_info) {
+ if (dateobj->time->is_localtime/* && dateobj->time->tz_info*/) {
date_instantiate(date_ce_timezone, return_value TSRMLS_CC);
tzobj = (php_timezone_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
- tzobj->tz = timelib_tzinfo_clone(dateobj->time->tz_info);
+ 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;
+ }
} else {
RETURN_FALSE;
}
@@ -2003,10 +2088,13 @@ PHP_FUNCTION(date_timezone_set)
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");
+ }
if (dateobj->time->tz_info) {
timelib_tzinfo_dtor(dateobj->time->tz_info);
}
- timelib_set_timezone(dateobj->time, timelib_tzinfo_clone(tzobj->tz));
+ timelib_set_timezone(dateobj->time, timelib_tzinfo_clone(tzobj->tzi.tz));
timelib_unixtime2local(dateobj->time, dateobj->time->sse);
}
/* }}} */
@@ -2025,10 +2113,20 @@ PHP_FUNCTION(date_offset_get)
}
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
- if (dateobj->time->is_localtime && dateobj->time->tz_info) {
- offset = timelib_get_time_zone_info(dateobj->time->sse, dateobj->time->tz_info);
- RETVAL_LONG(offset->offset);
- timelib_time_offset_dtor(offset);
+ if (dateobj->time->is_localtime/* && dateobj->time->tz_info*/) {
+ switch (dateobj->time->zone_type) {
+ case TIMELIB_ZONETYPE_ID:
+ offset = timelib_get_time_zone_info(dateobj->time->sse, dateobj->time->tz_info);
+ RETVAL_LONG(offset->offset);
+ timelib_time_offset_dtor(offset);
+ break;
+ case TIMELIB_ZONETYPE_OFFSET:
+ RETVAL_LONG(dateobj->time->z * -60);
+ break;
+ case TIMELIB_ZONETYPE_ABBR:
+ RETVAL_LONG((dateobj->time->z - (60 * dateobj->time->dst)) * -60);
+ break;
+ }
return;
} else {
RETURN_LONG(0);
@@ -2149,6 +2247,7 @@ 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;
@@ -2156,7 +2255,9 @@ PHP_FUNCTION(timezone_open)
if (SUCCESS != timezone_initialize(&tzi, tz TSRMLS_CC)) {
RETURN_FALSE;
}
- ((php_timezone_obj *) zend_object_store_get_object(date_instantiate(date_ce_timezone, return_value TSRMLS_CC) TSRMLS_CC))->tz = tzi;
+ tzobj = zend_object_store_get_object(date_instantiate(date_ce_timezone, return_value TSRMLS_CC) TSRMLS_CC);
+ tzobj->type = TIMELIB_ZONETYPE_ID;
+ tzobj->tzi.tz = tzi;
}
/* }}} */
@@ -2168,11 +2269,14 @@ PHP_METHOD(DateTimeZone, __construct)
char *tz;
int tz_len;
timelib_tzinfo *tzi = NULL;
+ php_timezone_obj *tzobj;
php_set_error_handling(EH_THROW, NULL TSRMLS_CC);
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len)) {
if (SUCCESS == timezone_initialize(&tzi, tz TSRMLS_CC)) {
- ((php_timezone_obj *) zend_object_store_get_object(getThis() TSRMLS_CC))->tz = tzi;
+ tzobj = zend_object_store_get_object(getThis() TSRMLS_CC);
+ tzobj->type = TIMELIB_ZONETYPE_ID;
+ tzobj->tzi.tz = tzi;
} else {
ZVAL_NULL(getThis());
}
@@ -2193,9 +2297,28 @@ PHP_FUNCTION(timezone_name_get)
RETURN_FALSE;
}
tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
- DATE_CHECK_INITIALIZED(tzobj->tz, DateTimeZone);
+ DATE_CHECK_INITIALIZED(tzobj->tzi.tz, DateTimeZone);
+
+ switch (tzobj->type) {
+ case TIMELIB_ZONETYPE_ID:
+ RETURN_STRING(tzobj->tzi.tz->name, 1);
+ break;
+ case TIMELIB_ZONETYPE_OFFSET: {
+ char *tmpstr = emalloc(sizeof("UTC+05:00"));
+ timelib_sll utc_offset = tzobj->tzi.utc_offset;
+
+ snprintf(tmpstr, sizeof("+05:00"), "%c%02d:%02d",
+ utc_offset > 0 ? '-' : '+',
+ abs(utc_offset / 60),
+ abs((utc_offset % 60)));
- RETURN_STRING(tzobj->tz->name, 1);
+ RETURN_STRING(tmpstr, 0);
+ }
+ break;
+ case TIMELIB_ZONETYPE_ABBR:
+ RETURN_STRING(tzobj->tzi.z.abbr, 1);
+ break;
+ }
}
/* }}} */
@@ -2237,11 +2360,11 @@ PHP_FUNCTION(timezone_offset_get)
RETURN_FALSE;
}
tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
- DATE_CHECK_INITIALIZED(tzobj->tz, DateTimeZone);
+ DATE_CHECK_INITIALIZED(tzobj->tzi.tz, DateTimeZone);
dateobj = (php_date_obj *) zend_object_store_get_object(dateobject TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
- offset = timelib_get_time_zone_info(dateobj->time->sse, tzobj->tz);
+ offset = timelib_get_time_zone_info(dateobj->time->sse, tzobj->tzi.tz);
RETVAL_LONG(offset->offset);
timelib_time_offset_dtor(offset);
}
@@ -2260,17 +2383,20 @@ PHP_FUNCTION(timezone_transitions_get)
RETURN_FALSE;
}
tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
- DATE_CHECK_INITIALIZED(tzobj->tz, DateTimeZone);
+ DATE_CHECK_INITIALIZED(tzobj->tzi.tz, DateTimeZone);
+ if (tzobj->type != TIMELIB_ZONETYPE_ID) {
+ RETURN_FALSE;
+ }
array_init(return_value);
- for (i = 0; i < tzobj->tz->timecnt; ++i) {
+ for (i = 0; i < tzobj->tzi.tz->timecnt; ++i) {
MAKE_STD_ZVAL(element);
array_init(element);
- add_assoc_long(element, "ts", tzobj->tz->trans[i]);
- add_assoc_string(element, "time", php_format_date(DATE_FORMAT_ISO8601, 13, tzobj->tz->trans[i], 0 TSRMLS_CC), 0);
- add_assoc_long(element, "offset", tzobj->tz->type[tzobj->tz->trans_idx[i]].offset);
- add_assoc_bool(element, "isdst", tzobj->tz->type[tzobj->tz->trans_idx[i]].isdst);
- add_assoc_string(element, "abbr", &tzobj->tz->timezone_abbr[tzobj->tz->type[tzobj->tz->trans_idx[i]].abbr_idx], 1);
+ add_assoc_long(element, "ts", tzobj->tzi.tz->trans[i]);
+ add_assoc_string(element, "time", php_format_date(DATE_FORMAT_ISO8601, 13, tzobj->tzi.tz->trans[i], 0 TSRMLS_CC), 0);
+ add_assoc_long(element, "offset", tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].offset);
+ add_assoc_bool(element, "isdst", tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].isdst);
+ add_assoc_string(element, "abbr", &tzobj->tzi.tz->timezone_abbr[tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].abbr_idx], 1);
add_next_index_zval(return_value, element);
}
diff --git a/ext/date/tests/bug40743.phpt b/ext/date/tests/bug40743.phpt
new file mode 100644
index 0000000000..f3ce17124d
--- /dev/null
+++ b/ext/date/tests/bug40743.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #40743 (DateTime ignores the TimeZone object passed to the constructor)
+--FILE--
+<?php
+$dt = new DateTime('@1200506699', new DateTimeZone('Europe/Berlin'));
+echo $dt->format(DATE_RFC822), "\n";
+echo $dt->format('T e Z'), "\n";
+echo "-----\n";
+
+date_default_timezone_set('America/New_York');
+
+$dt = new DateTime('16 Jan 08 13:04:59');
+echo $dt->format(DATE_RFC822 . " e T O U"), "\n";
+
+$dt = new DateTime('@1200506699');
+echo $dt->format(DATE_RFC822 . " e T O U"), "\n";
+
+$dt = new DateTime('@1200506699');
+$dt->setTimezone( new DateTimeZone( 'America/New_York' ) );
+echo $dt->format(DATE_RFC822 . " e T O U"), "\n";
+
+$dt = new DateTime('@1200506699', new DateTimeZone('Europe/Berlin'));
+echo $dt->format(DATE_RFC822 . " e T O U"), "\n";
+
+$dt = new DateTime('16 Jan 08 13:04:59 America/Chicago');
+echo $dt->format(DATE_RFC822 . " e T O U"), "\n";
+
+$dt = new DateTime('16 Jan 08 13:04:59 America/Chicago', new DateTimeZone('Europe/Berlin'));
+echo $dt->format(DATE_RFC822 . " e T O U"), "\n";
+?>
+--EXPECT--
+Wed, 16 Jan 08 18:04:59 +0000
+GMT+0000 +00:00 0
+-----
+Wed, 16 Jan 08 13:04:59 -0500 America/New_York EST -0500 1200506699
+Wed, 16 Jan 08 18:04:59 +0000 +00:00 GMT+0000 +0000 1200506699
+Wed, 16 Jan 08 13:04:59 -0500 America/New_York EST -0500 1200506699
+Wed, 16 Jan 08 18:04:59 +0000 +00:00 GMT+0000 +0000 1200506699
+Wed, 16 Jan 08 13:04:59 -0600 America/Chicago CST -0600 1200510299
+Wed, 16 Jan 08 13:04:59 -0600 America/Chicago CST -0600 1200510299
diff --git a/ext/date/tests/bug42910.phpt b/ext/date/tests/bug42910.phpt
new file mode 100644
index 0000000000..1bd0790812
--- /dev/null
+++ b/ext/date/tests/bug42910.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #42910 (Constructing DateTime with TimeZone Indicator invalidates DateTimeZone)
+--FILE--
+<?php
+ date_default_timezone_set('America/Los_Angeles');
+ $foo = new DateTime('2007-03-11');
+ $bar = new DateTime('2007-03-11T00:00:00-0800');
+
+ print $foo->format(DateTime::ISO8601) . ' - ' . $foo->getTimezone()->getName() . ' - ' . $foo->format('U') . "\r\n";
+ print $bar->format(DateTime::ISO8601) . ' - ' . $bar->getTimezone()->getName() . ' - ' . $bar->format('U') . "\r\n";
+
+ $foo->setDate(2007, 03, 12);
+ $bar->setDate(2007, 03, 12);
+
+ print $foo->format(DateTime::ISO8601) . ' - ' . $foo->getTimezone()->getName() . ' - ' . $foo->format('U') . "\r\n";
+ print $bar->format(DateTime::ISO8601) . ' - ' . $bar->getTimezone()->getName() . ' - ' . $bar->format('U') . "\r\n";
+
+// --------------
+
+ date_default_timezone_set('Australia/Sydney');
+
+ $date= date_create('2007-11-04 12:00:00+0200');
+ var_dump(date_format($date, 'O e'));
+?>
+--EXPECT--
+2007-03-11T00:00:00-0800 - America/Los_Angeles - 1173600000
+2007-03-11T00:00:00-0800 - -08:00 - 1173600000
+2007-03-12T00:00:00-0700 - America/Los_Angeles - 1173682800
+2007-03-12T00:00:00-0800 - -08:00 - 1173686400
+string(12) "+0200 +02:00"
diff --git a/ext/date/tests/bug43527.phpt b/ext/date/tests/bug43527.phpt
new file mode 100644
index 0000000000..cc69def7be
--- /dev/null
+++ b/ext/date/tests/bug43527.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Bug #43527 (DateTime created from a timestamp reports environment timezone)
+--FILE--
+<?php
+date_default_timezone_set("Etc/GMT+1");
+$datetime = new DateTime('Fri, 07 Dec 2007 19:05:14 +1000');
+echo $datetime->getTimezone()->getName(), "\n";
+?>
+--EXPECT--
++10:00