From 495b26084f12d91b17822f5a7e2aea116ef05379 Mon Sep 17 00:00:00 2001 From: Michael Moravec Date: Mon, 17 Apr 2017 18:36:30 +0200 Subject: [PATCH] Added method DateTime::createFromImmutable() --- NEWS | 2 + ext/date/php_date.c | 38 ++++++++++++++----- ext/date/php_date.h | 1 + .../tests/DateTime_createFromImmutable.phpt | 32 ++++++++++++++++ ext/date/tests/DateTime_verify.phpt | 37 ++++++++++-------- 5 files changed, 86 insertions(+), 24 deletions(-) create mode 100644 ext/date/tests/DateTime_createFromImmutable.phpt diff --git a/NEWS b/NEWS index 03176f8df40a9..4a46e260853dd 100644 --- a/NEWS +++ b/NEWS @@ -65,6 +65,8 @@ PHP NEWS . Fixed bug #74404 (Wrong reflection on DateTimeZone::getTransitions). (krakjoe) . Fixed bug #74080 (add constant for RFC7231 format datetime). (duncan3dc) + . Implemented FR #74668: Add DateTime::createFromImmutable() method. + (bugs dot php dot net at majkl578 dot cz, Rican7) - Dba: . Fixed bug #72885 (flatfile: dba_fetch() fails to read replaced entry). diff --git a/ext/date/php_date.c b/ext/date/php_date.c index f304f5545302d..489a6a30f0470 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -309,6 +309,11 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_date_method_timestamp_get, 0) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_create_from_immutable, 0, 0, 1) + ZEND_ARG_INFO(0, DateTimeImmutable) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_create_from_mutable, 0, 0, 1) ZEND_ARG_INFO(0, DateTime) ZEND_END_ARG_INFO() @@ -472,6 +477,7 @@ const zend_function_entry date_funcs_date[] = { PHP_ME(DateTime, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC) PHP_ME(DateTime, __wakeup, NULL, ZEND_ACC_PUBLIC) PHP_ME(DateTime, __set_state, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(DateTime, createFromImmutable, arginfo_date_method_create_from_immutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME_MAPPING(createFromFormat, date_create_from_format, arginfo_date_create_from_format, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_date_get_last_errors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME_MAPPING(format, date_format, arginfo_date_method_format, 0) @@ -2816,7 +2822,28 @@ PHP_METHOD(DateTimeImmutable, __construct) } /* }}} */ -/* {{{ proto DateTimeImmutable::createFromMutable(DateTimeZone object) +/* {{{ proto DateTime::createFromImmutable(DateTimeImmutable object) + Creates new DateTime object from an existing immutable DateTimeImmutable object. +*/ +PHP_METHOD(DateTime, createFromImmutable) +{ + zval *datetimeimmutable_object = NULL; + php_date_obj *new_obj = NULL; + php_date_obj *old_obj = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS(datetimeimmutable_object, date_ce_immutable) + ZEND_PARSE_PARAMETERS_END(); + + php_date_instantiate(date_ce_date, return_value); + old_obj = Z_PHPDATE_P(datetimeimmutable_object); + new_obj = Z_PHPDATE_P(return_value); + + new_obj->time = timelib_time_clone(old_obj->time); +} +/* }}} */ + +/* {{{ proto DateTimeImmutable::createFromMutable(DateTime object) Creates new DateTimeImmutable object from an existing mutable DateTime object. */ PHP_METHOD(DateTimeImmutable, createFromMutable) @@ -2833,14 +2860,7 @@ PHP_METHOD(DateTimeImmutable, createFromMutable) old_obj = Z_PHPDATE_P(datetime_object); new_obj = Z_PHPDATE_P(return_value); - new_obj->time = timelib_time_ctor(); - *new_obj->time = *old_obj->time; - if (old_obj->time->tz_abbr) { - new_obj->time->tz_abbr = timelib_strdup(old_obj->time->tz_abbr); - } - if (old_obj->time->tz_info) { - new_obj->time->tz_info = old_obj->time->tz_info; - } + new_obj->time = timelib_time_clone(old_obj->time); } /* }}} */ diff --git a/ext/date/php_date.h b/ext/date/php_date.h index 827d0b9deb5b2..6f39a333d9cf5 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -53,6 +53,7 @@ PHP_FUNCTION(getdate); PHP_METHOD(DateTime, __construct); PHP_METHOD(DateTime, __wakeup); PHP_METHOD(DateTime, __set_state); +PHP_METHOD(DateTime, createFromImmutable); PHP_FUNCTION(date_create); PHP_FUNCTION(date_create_immutable); PHP_FUNCTION(date_create_from_format); diff --git a/ext/date/tests/DateTime_createFromImmutable.phpt b/ext/date/tests/DateTime_createFromImmutable.phpt new file mode 100644 index 0000000000000..ee7731855a630 --- /dev/null +++ b/ext/date/tests/DateTime_createFromImmutable.phpt @@ -0,0 +1,32 @@ +--TEST-- +Tests for DateTime::createFromImmutable. +--INI-- +date.timezone=Europe/London +--FILE-- +modify('+ 1 hour'); + +var_dump( $i->format('Y-m-d H:i:s') === $current ); + +$m = DateTime::createFromImmutable( date_create( $current ) ); +var_dump( $m ); +?> +--EXPECTF-- +object(DateTime)#%d (3) { + ["date"]=> + string(26) "2014-03-02 16:24:08.000000" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(13) "Europe/London" +} +bool(true) + +Warning: DateTime::createFromImmutable() expects parameter 1 to be DateTimeImmutable, object given in %stests%eDateTime_createFromImmutable.php on line %d +NULL diff --git a/ext/date/tests/DateTime_verify.phpt b/ext/date/tests/DateTime_verify.phpt index bb3ed9909a3ac..b8626623ef726 100644 --- a/ext/date/tests/DateTime_verify.phpt +++ b/ext/date/tests/DateTime_verify.phpt @@ -27,7 +27,7 @@ object(ReflectionClass)#%d (1) { string(8) "DateTime" } ..and get names of all its methods -array(18) { +array(19) { [0]=> object(ReflectionMethod)#%d (2) { ["name"]=> @@ -52,102 +52,109 @@ array(18) { [3]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(16) "createFromFormat" + string(19) "createFromImmutable" ["class"]=> string(8) "DateTime" } [4]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(13) "getLastErrors" + string(16) "createFromFormat" ["class"]=> string(8) "DateTime" } [5]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(6) "format" + string(13) "getLastErrors" ["class"]=> string(8) "DateTime" } [6]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(6) "modify" + string(6) "format" ["class"]=> string(8) "DateTime" } [7]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(3) "add" + string(6) "modify" ["class"]=> string(8) "DateTime" } [8]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(3) "sub" + string(3) "add" ["class"]=> string(8) "DateTime" } [9]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(11) "getTimezone" + string(3) "sub" ["class"]=> string(8) "DateTime" } [10]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(11) "setTimezone" + string(11) "getTimezone" ["class"]=> string(8) "DateTime" } [11]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(9) "getOffset" + string(11) "setTimezone" ["class"]=> string(8) "DateTime" } [12]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(7) "setTime" + string(9) "getOffset" ["class"]=> string(8) "DateTime" } [13]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(7) "setDate" + string(7) "setTime" ["class"]=> string(8) "DateTime" } [14]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(10) "setISODate" + string(7) "setDate" ["class"]=> string(8) "DateTime" } [15]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(12) "setTimestamp" + string(10) "setISODate" ["class"]=> string(8) "DateTime" } [16]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(12) "getTimestamp" + string(12) "setTimestamp" ["class"]=> string(8) "DateTime" } [17]=> + object(ReflectionMethod)#%d (2) { + ["name"]=> + string(12) "getTimestamp" + ["class"]=> + string(8) "DateTime" + } + [18]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(4) "diff"