]> granicus.if.org Git - php/commitdiff
Adding DateTime(Immutable)::createFromInterface()
authormike <mike.simonson@gmail.com>
Mon, 16 Dec 2019 13:31:14 +0000 (14:31 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 3 Jan 2020 15:55:12 +0000 (16:55 +0100)
These are like

    DateTime::createFromImmutable()
    DateTimeImmutable::createFromMutable()

but accept any DateTimeInterface instead.

Closes GH-5016.

UPGRADING
ext/date/php_date.c
ext/date/php_date.h
ext/date/php_date.stub.php
ext/date/php_date_arginfo.h
ext/date/tests/DateTimeImmutable_createFromInterface.phpt [new file with mode: 0644]
ext/date/tests/DateTime_createFromInterface.phpt [new file with mode: 0644]

index 886d1d4796ffba19d49c967bb6efcf5bb92d4613..b63eed4597568a67add2290fbe3df0e64ead4950 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -334,6 +334,10 @@ PHP 8.0 UPGRADE NOTES
     RFC: https://wiki.php.net/rfc/weak_maps
   . Added ValueError class.
 
+- Date:
+  . Added DateTime::createFromInterface() and
+    DateTimeImmutable::createFromInterface().
+
 ========================================
 3. Changes in SAPI modules
 ========================================
index 2f5d9af22a557d71ef2d87c9e158b0923715d559..362bd711b6d3c3c8609ed700844c35f01a7ec94c 100644 (file)
@@ -153,6 +153,7 @@ static const zend_function_entry date_funcs_date[] = {
        PHP_ME(DateTime,                        __wakeup,                       arginfo_class_DateTimeInterface___wakeup, ZEND_ACC_PUBLIC)
        PHP_ME(DateTime,                        __set_state,            arginfo_class_DateTime___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
        PHP_ME(DateTime,                        createFromImmutable,    arginfo_class_DateTime_createFromImmutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       PHP_ME(DateTime,                        createFromInterface,    arginfo_class_DateTime_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
        PHP_ME_MAPPING(createFromFormat, date_create_from_format,       arginfo_class_DateTime_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
        PHP_ME_MAPPING(getLastErrors, date_get_last_errors,     arginfo_class_DateTime_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
        PHP_ME_MAPPING(format,          date_format,            arginfo_class_DateTimeInterface_format, 0)
@@ -191,6 +192,7 @@ static const zend_function_entry date_funcs_immutable[] = {
        PHP_ME(DateTimeImmutable, setISODate,    arginfo_class_DateTimeImmutable_setISODate, 0)
        PHP_ME(DateTimeImmutable, setTimestamp,  arginfo_class_DateTimeImmutable_setTimestamp, 0)
        PHP_ME(DateTimeImmutable, createFromMutable, arginfo_class_DateTimeImmutable_createFromMutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+       PHP_ME(DateTimeImmutable, createFromInterface, arginfo_class_DateTimeImmutable_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
        PHP_FE_END
 };
 
@@ -2545,6 +2547,27 @@ PHP_METHOD(DateTime, createFromImmutable)
 }
 /* }}} */
 
+/* {{{ proto DateTime::createFromInterface(DateTimeInterface object)
+   Creates new DateTime object from an existing DateTimeInterface object.
+*/
+PHP_METHOD(DateTime, createFromInterface)
+{
+       zval *datetimeinterface_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(datetimeinterface_object, date_ce_interface)
+       ZEND_PARSE_PARAMETERS_END();
+
+       php_date_instantiate(date_ce_date, return_value);
+       old_obj = Z_PHPDATE_P(datetimeinterface_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.
 */
@@ -2566,6 +2589,27 @@ PHP_METHOD(DateTimeImmutable, createFromMutable)
 }
 /* }}} */
 
+/* {{{ proto DateTimeImmutable::createFromInterface(DateTimeInterface object)
+   Creates new DateTimeImmutable object from an existing DateTimeInterface object.
+*/
+PHP_METHOD(DateTimeImmutable, createFromInterface)
+{
+       zval *datetimeinterface_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(datetimeinterface_object, date_ce_interface)
+       ZEND_PARSE_PARAMETERS_END();
+
+       php_date_instantiate(date_ce_immutable, return_value);
+       old_obj = Z_PHPDATE_P(datetimeinterface_object);
+       new_obj = Z_PHPDATE_P(return_value);
+
+       new_obj->time = timelib_time_clone(old_obj->time);
+}
+/* }}} */
+
 static int php_date_initialize_from_hash(php_date_obj **dateobj, HashTable *myht)
 {
        zval             *z_date;
index 57a9e28d883b9dfa684772def39075c49f2df4c3..8458b0187e235d37f50f2162f0b3eae7944543d8 100644 (file)
@@ -46,6 +46,7 @@ PHP_METHOD(DateTime, __construct);
 PHP_METHOD(DateTime, __wakeup);
 PHP_METHOD(DateTime, __set_state);
 PHP_METHOD(DateTime, createFromImmutable);
+PHP_METHOD(DateTime, createFromInterface);
 PHP_FUNCTION(date_create);
 PHP_FUNCTION(date_create_immutable);
 PHP_FUNCTION(date_create_from_format);
@@ -79,6 +80,7 @@ PHP_METHOD(DateTimeImmutable, setDate);
 PHP_METHOD(DateTimeImmutable, setISODate);
 PHP_METHOD(DateTimeImmutable, setTimestamp);
 PHP_METHOD(DateTimeImmutable, createFromMutable);
+PHP_METHOD(DateTimeImmutable, createFromInterface);
 
 PHP_METHOD(DateTimeZone, __construct);
 PHP_METHOD(DateTimeZone, __wakeup);
index 17d9a848f097c9fd564ef6266cf6317f4d716213..e9985dd6b221604e1d111e90c3b722d9474561d9 100644 (file)
@@ -146,6 +146,8 @@ class DateTime implements DateTimeInterface {
     /** @return DateTime */
     public static function createFromImmutable(DateTimeImmutable $object);
 
+    public static function createFromInterface(DateTimeInterface $object): DateTime;
+
     /** @return DateTime|false */
     public static function createFromFormat(
         string $format, string $time, ?DateTimeZone $timezone = null);
@@ -187,6 +189,8 @@ class DateTimeImmutable implements DateTimeInterface {
     /** @return DateTimeImmutable */
     public static function createFromMutable(DateTime $object);
 
+    public static function createFromInterface(DateTimeInterface $object): DateTimeImmutable;
+
     /** @return DateTimeImmutable|false */
     public static function createFromFormat(
         string $format, string $time, ?DateTimeZone $timezone = null);
index 183e3e0d30a30fe6ac1d2d2946590399f88ca95e..acf6ddd663f8434348af27a51ffc099171fff705 100644 (file)
@@ -257,6 +257,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_createFromImmutable, 0, 0, 1)
        ZEND_ARG_OBJ_INFO(0, object, DateTimeImmutable, 0)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_createFromInterface, 0, 1, DateTime, 0)
+       ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_createFromFormat, 0, 0, 2)
        ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
@@ -310,6 +314,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeImmutable_createFromMutable, 0, 0,
        ZEND_ARG_OBJ_INFO(0, object, DateTime, 0)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_createFromInterface, 0, 1, DateTimeImmutable, 0)
+       ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0)
+ZEND_END_ARG_INFO()
+
 #define arginfo_class_DateTimeImmutable_createFromFormat arginfo_class_DateTime_createFromFormat
 
 #define arginfo_class_DateTimeImmutable_getLastErrors arginfo_class_DateTimeInterface_getTimezone
diff --git a/ext/date/tests/DateTimeImmutable_createFromInterface.phpt b/ext/date/tests/DateTimeImmutable_createFromInterface.phpt
new file mode 100644 (file)
index 0000000..31e3847
--- /dev/null
@@ -0,0 +1,79 @@
+--TEST--
+Tests for DateTimeImmutable::createFromInterface
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+$current = "2014-03-02 16:24:08";
+
+$i = DateTimeImmutable::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = DateTimeImmutable::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+
+$current = "2019-12-16 15:06:46 CET";
+
+$i = DateTimeImmutable::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = DateTimeImmutable::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+
+$current = "2019-12-16 15:08:20 +0100";
+
+$i = DateTimeImmutable::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = DateTimeImmutable::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+?>
+--EXPECTF--
+object(DateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+object(DateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+object(DateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:06:46.000000"
+  ["timezone_type"]=>
+  int(2)
+  ["timezone"]=>
+  string(3) "CET"
+}
+object(DateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:06:46.000000"
+  ["timezone_type"]=>
+  int(2)
+  ["timezone"]=>
+  string(3) "CET"
+}
+object(DateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:08:20.000000"
+  ["timezone_type"]=>
+  int(1)
+  ["timezone"]=>
+  string(6) "+01:00"
+}
+object(DateTimeImmutable)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:08:20.000000"
+  ["timezone_type"]=>
+  int(1)
+  ["timezone"]=>
+  string(6) "+01:00"
+}
diff --git a/ext/date/tests/DateTime_createFromInterface.phpt b/ext/date/tests/DateTime_createFromInterface.phpt
new file mode 100644 (file)
index 0000000..a1ad5a3
--- /dev/null
@@ -0,0 +1,79 @@
+--TEST--
+Tests for DateTime::createFromInterface
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+$current = "2014-03-02 16:24:08";
+
+$i = DateTime::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = DateTime::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+
+$current = "2019-12-16 15:06:46 CET";
+
+$i = DateTime::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = DateTime::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+
+$current = "2019-12-16 15:08:20 +0100";
+
+$i = DateTime::createFromInterface( date_create( $current ) );
+var_dump( $i );
+
+$i = DateTime::createFromInterface( date_create_immutable( $current ) );
+var_dump( $i );
+?>
+--EXPECTF--
+object(DateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+object(DateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2014-03-02 16:24:08.000000"
+  ["timezone_type"]=>
+  int(3)
+  ["timezone"]=>
+  string(13) "Europe/London"
+}
+object(DateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:06:46.000000"
+  ["timezone_type"]=>
+  int(2)
+  ["timezone"]=>
+  string(3) "CET"
+}
+object(DateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:06:46.000000"
+  ["timezone_type"]=>
+  int(2)
+  ["timezone"]=>
+  string(3) "CET"
+}
+object(DateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:08:20.000000"
+  ["timezone_type"]=>
+  int(1)
+  ["timezone"]=>
+  string(6) "+01:00"
+}
+object(DateTime)#%d (3) {
+  ["date"]=>
+  string(26) "2019-12-16 15:08:20.000000"
+  ["timezone_type"]=>
+  int(1)
+  ["timezone"]=>
+  string(6) "+01:00"
+}