summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerick Rethans <github@derickrethans.nl>2014-01-26 14:02:44 +0100
committerDerick Rethans <github@derickrethans.nl>2014-01-26 14:02:44 +0100
commit2e65908643a22c0ffabf604bd948912eb7b95226 (patch)
tree26010ccb59aa896ca97eb80b07525fcc2356c7b1
parent6d6850b3b8521364f0950242c49ab774cfd97dce (diff)
parent7399386a2094ccce9b5deb0c035ff6ac2aa7eb8b (diff)
downloadphp-git-2e65908643a22c0ffabf604bd948912eb7b95226.tar.gz
Merge branch 'PHP-5.5' into PHP-5.6
-rw-r--r--ext/date/lib/timelib.h2
-rw-r--r--ext/date/lib/timelib_structs.h6
-rw-r--r--ext/date/lib/unixtime2tm.c28
-rw-r--r--ext/date/php_date.c15
-rw-r--r--ext/date/php_date.h11
-rw-r--r--ext/date/tests/bug45543.phpt34
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
+