From 29eca466bb2f07c4d41eeefc5417eaa64eb14d3a Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Tue, 10 Oct 2023 18:34:22 +0200 Subject: [PATCH 1/5] Added DateTime[Immutable]::createFromTimestamp / date_create_[immutable]_from_timestamp --- Zend/Optimizer/zend_func_infos.h | 2 + ext/date/php_date.c | 96 +++++- ext/date/php_date.stub.php | 18 + ext/date/php_date_arginfo.h | 24 +- ext/date/tests/createFromTimestamp.phpt | 421 ++++++++++++++++++++++++ 5 files changed, 559 insertions(+), 2 deletions(-) create mode 100644 ext/date/tests/createFromTimestamp.phpt diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index 6dc947e3cc839..35e28c82307e9 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -54,6 +54,8 @@ static const func_info_t func_infos[] = { F1("date_create_immutable", MAY_BE_OBJECT|MAY_BE_FALSE), F1("date_create_from_format", MAY_BE_OBJECT|MAY_BE_FALSE), F1("date_create_immutable_from_format", MAY_BE_OBJECT|MAY_BE_FALSE), + F1("date_create_from_timestamp", MAY_BE_OBJECT|MAY_BE_FALSE), + F1("date_create_immutable_from_timestamp", MAY_BE_OBJECT|MAY_BE_FALSE), F1("date_parse", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY), F1("date_parse_from_format", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY), F1("date_get_last_errors", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE), diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 96c37092511fd..9cd5ca04d753f 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2500,6 +2500,40 @@ PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, siz return 1; } /* }}} */ +PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec) /* {{{ */ +{ + dateobj->time = timelib_time_ctor(); + dateobj->time->zone_type = TIMELIB_ZONETYPE_OFFSET; + dateobj->time->z = (timelib_sll)0; + dateobj->time->have_relative = 0; + + timelib_unixtime2gmt(dateobj->time, (timelib_sll)sec); + timelib_update_ts(dateobj->time, NULL); + php_date_set_time_fraction(dateobj->time, usec); +} /* }}} */ + +PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) /* {{{ */ +{ + zend_long sec; + int usec; + + if (UNEXPECTED(isnan(ts) || !ZEND_DOUBLE_FITS_LONG(ts))) { + return 0; + } + + sec = (zend_long)ts; + usec = (int)(fmod(ts, 1) * 1000000); + + if (UNEXPECTED(usec < 0)) { + sec = sec - 1; + usec = 1000000 + usec; + } + + php_date_initialize_from_ts_long(dateobj, sec, usec); + + return 1; +} /* }}} */ + /* {{{ Returns new DateTime object */ PHP_FUNCTION(date_create) { @@ -2564,7 +2598,7 @@ PHP_FUNCTION(date_create_from_format) } /* }}} */ -/* {{{ Returns new DateTime object formatted according to the specified format */ +/* {{{ Returns new DateTimeImmutable object formatted according to the specified format */ PHP_FUNCTION(date_create_immutable_from_format) { zval *timezone_object = NULL; @@ -2586,6 +2620,66 @@ PHP_FUNCTION(date_create_immutable_from_format) } /* }}} */ +/* {{{ Returns new DateTime object from given unix timetamp */ +PHP_FUNCTION(date_create_from_timestamp) +{ + php_date_obj *dateobj; + zval *value; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_NUMBER(value) + ZEND_PARSE_PARAMETERS_END(); + + php_date_instantiate(date_ce_date, return_value); + dateobj = Z_PHPDATE_P(return_value); + + switch (Z_TYPE_P(value)) { + case IS_LONG: + php_date_initialize_from_ts_long(dateobj, Z_LVAL_P(value), 0); + break; + + case IS_DOUBLE: + if (!php_date_initialize_from_ts_double(dateobj, Z_DVAL_P(value))) { + zval_ptr_dtor(return_value); + RETURN_FALSE; + } + break; + + EMPTY_SWITCH_DEFAULT_CASE(); + } +} +/* }}} */ + +/* {{{ Returns new DateTimeImmutable object from given unix timestamp */ +PHP_FUNCTION(date_create_immutable_from_timestamp) +{ + php_date_obj *dateobj; + zval *value; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_NUMBER(value) + ZEND_PARSE_PARAMETERS_END(); + + php_date_instantiate(date_ce_immutable, return_value); + dateobj = Z_PHPDATE_P(return_value); + + switch (Z_TYPE_P(value)) { + case IS_LONG: + php_date_initialize_from_ts_long(dateobj, Z_LVAL_P(value), 0); + break; + + case IS_DOUBLE: + if (!php_date_initialize_from_ts_double(dateobj, Z_DVAL_P(value))) { + zval_ptr_dtor(return_value); + RETURN_FALSE; + } + break; + + EMPTY_SWITCH_DEFAULT_CASE(); + } +} +/* }}} */ + /* {{{ Creates new DateTime object */ PHP_METHOD(DateTime, __construct) { diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index e0717fa7f4c85..f12bb4c996fee 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -159,6 +159,12 @@ function date_create_from_format( function date_create_immutable_from_format( string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false {} +/** @refcount 1 */ +function date_create_from_timestamp(int|float $timestamp): DateTime|false {} + +/** @refcount 1 */ +function date_create_immutable_from_timestamp(int|float $timestamp): DateTimeImmutable|false {} + /** * @return array * @refcount 1 @@ -362,6 +368,12 @@ public static function createFromInterface(DateTimeInterface $object): DateTime */ public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false {} + /** + * @tentative-return-type + * @alias date_create_from_timestamp + */ + public static function createFromTimestamp(int|float $timestamp): DateTime|false {} + /** * @return array|false * @tentative-return-type @@ -466,6 +478,12 @@ public static function __set_state(array $array): DateTimeImmutable {} */ public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false {} + /** + * @tentative-return-type + * @alias date_create_immutable_from_timestamp + */ + public static function createFromTimestamp(int|float $timestamp): DateTimeImmutable|false {} + /** * @return array|false * @tentative-return-type diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index bbede1f39596e..d2c51f4af9a82 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0f204ac6646be79b515189a384fce9bcea9a4f42 */ + * Stub hash: d4cdf0d730b96add41971f720191db9567bd8180 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) @@ -76,6 +76,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_immutable_from_f ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_from_timestamp, 0, 1, DateTime, MAY_BE_FALSE) + ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_immutable_from_timestamp, 0, 1, DateTimeImmutable, MAY_BE_FALSE) + ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_date_parse, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -280,6 +288,10 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTime_cre ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTime_createFromTimestamp, 0, 1, DateTime, MAY_BE_FALSE) + ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_DateTime_getLastErrors, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_END_ARG_INFO() @@ -348,6 +360,10 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTimeImmu ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTimeImmutable_createFromTimestamp, 0, 1, DateTimeImmutable, MAY_BE_FALSE) + ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) +ZEND_END_ARG_INFO() + #define arginfo_class_DateTimeImmutable_getLastErrors arginfo_class_DateTime_getLastErrors #define arginfo_class_DateTimeImmutable_format arginfo_class_DateTimeInterface_format @@ -515,6 +531,8 @@ ZEND_FUNCTION(date_create); ZEND_FUNCTION(date_create_immutable); ZEND_FUNCTION(date_create_from_format); ZEND_FUNCTION(date_create_immutable_from_format); +ZEND_FUNCTION(date_create_from_timestamp); +ZEND_FUNCTION(date_create_immutable_from_timestamp); ZEND_FUNCTION(date_parse); ZEND_FUNCTION(date_parse_from_format); ZEND_FUNCTION(date_get_last_errors); @@ -612,6 +630,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(date_create_immutable, arginfo_date_create_immutable) ZEND_FE(date_create_from_format, arginfo_date_create_from_format) ZEND_FE(date_create_immutable_from_format, arginfo_date_create_immutable_from_format) + ZEND_FE(date_create_from_timestamp, arginfo_date_create_from_timestamp) + ZEND_FE(date_create_immutable_from_timestamp, arginfo_date_create_immutable_from_timestamp) ZEND_FE(date_parse, arginfo_date_parse) ZEND_FE(date_parse_from_format, arginfo_date_parse_from_format) ZEND_FE(date_get_last_errors, arginfo_date_get_last_errors) @@ -670,6 +690,7 @@ static const zend_function_entry class_DateTime_methods[] = { ZEND_ME(DateTime, createFromImmutable, arginfo_class_DateTime_createFromImmutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(DateTime, createFromInterface, arginfo_class_DateTime_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(createFromFormat, date_create_from_format, arginfo_class_DateTime_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME_MAPPING(createFromTimestamp, date_create_from_timestamp, arginfo_class_DateTime_createFromTimestamp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_class_DateTime_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(format, date_format, arginfo_class_DateTime_format, ZEND_ACC_PUBLIC) ZEND_ME(DateTime, modify, arginfo_class_DateTime_modify, ZEND_ACC_PUBLIC) @@ -695,6 +716,7 @@ static const zend_function_entry class_DateTimeImmutable_methods[] = { ZEND_ME(DateTimeImmutable, __wakeup, arginfo_class_DateTimeImmutable___wakeup, ZEND_ACC_PUBLIC) ZEND_ME(DateTimeImmutable, __set_state, arginfo_class_DateTimeImmutable___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(createFromFormat, date_create_immutable_from_format, arginfo_class_DateTimeImmutable_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME_MAPPING(createFromTimestamp, date_create_immutable_from_timestamp, arginfo_class_DateTimeImmutable_createFromTimestamp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_class_DateTimeImmutable_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(format, date_format, arginfo_class_DateTimeImmutable_format, ZEND_ACC_PUBLIC) ZEND_ME_MAPPING(getTimezone, date_timezone_get, arginfo_class_DateTimeImmutable_getTimezone, ZEND_ACC_PUBLIC) diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt new file mode 100644 index 0000000000000..d5c71ca22f7a9 --- /dev/null +++ b/ext/date/tests/createFromTimestamp.phpt @@ -0,0 +1,421 @@ +--TEST-- +Tests for DateTime[Immutable]::createFromTimestamp & date_create_[immutable_]_from_timestamp +--INI-- +date.timezone=Europe/London +--FILE-- + +--EXPECTF-- +date_create_from_timestamp(1696883232): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2023-10-09 20:27:12.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(1696883232): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2023-10-09 20:27:12.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(1696883232): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2023-10-09 20:27:12.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(1696883232): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2023-10-09 20:27:12.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(-1696883232): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1916-03-25 03:32:48.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-1696883232): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1916-03-25 03:32:48.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(-1696883232): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1916-03-25 03:32:48.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-1696883232): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1916-03-25 03:32:48.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(1696883232.013981): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2023-10-09 20:27:12.013981" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(1696883232.013981): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2023-10-09 20:27:12.013981" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(1696883232.013981): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2023-10-09 20:27:12.013981" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(1696883232.013981): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2023-10-09 20:27:12.013981" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(-1696883232.013981): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1916-03-25 03:32:47.986019" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-1696883232.013981): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1916-03-25 03:32:47.986019" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(-1696883232.013981): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1916-03-25 03:32:47.986019" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-1696883232.013981): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1916-03-25 03:32:47.986019" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(0.123456): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.123456" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(0.123456): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.123456" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(0.123456): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.123456" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(0.123456): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.123456" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(-0.123456): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1969-12-31 23:59:59.876544" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-0.123456): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1969-12-31 23:59:59.876544" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(-0.123456): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1969-12-31 23:59:59.876544" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-0.123456): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1969-12-31 23:59:59.876544" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(0): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(0): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(0): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(0): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(0.0): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(0.0): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(0.0): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(0.0): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(-0.0): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-0.0): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(-0.0): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-0.0): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(2147483647): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:07.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(2147483647): object(DateTime)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:07.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(2147483647): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:07.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(2147483647): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "2038-01-19 03:14:07.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(-2147483648): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:52.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-2147483648): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:52.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(-2147483648): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:52.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-2147483648): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:52.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(1.8446744073709552E+19): bool(false) +DateTime::createFromTimestamp(1.8446744073709552E+19): bool(false) +date_create_immutable_from_timestamp(1.8446744073709552E+19): bool(false) +DateTimeImmutable::createFromTimestamp(1.8446744073709552E+19): bool(false) +date_create_from_timestamp(-1.8446744073709552E+19): bool(false) +DateTime::createFromTimestamp(-1.8446744073709552E+19): bool(false) +date_create_immutable_from_timestamp(-1.8446744073709552E+19): bool(false) +DateTimeImmutable::createFromTimestamp(-1.8446744073709552E+19): bool(false) +date_create_from_timestamp(NAN): bool(false) +DateTime::createFromTimestamp(NAN): bool(false) +date_create_immutable_from_timestamp(NAN): bool(false) +DateTimeImmutable::createFromTimestamp(NAN): bool(false) +date_create_from_timestamp(INF): bool(false) +DateTime::createFromTimestamp(INF): bool(false) +date_create_immutable_from_timestamp(INF): bool(false) +DateTimeImmutable::createFromTimestamp(INF): bool(false) +date_create_from_timestamp(-INF): bool(false) +DateTime::createFromTimestamp(-INF): bool(false) +date_create_immutable_from_timestamp(-INF): bool(false) +DateTimeImmutable::createFromTimestamp(-INF): bool(false) From 9df735ef9b362769eaee211a6bad796a314e0bbe Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Thu, 12 Oct 2023 09:10:33 +0200 Subject: [PATCH 2/5] fixup --- ext/date/php_date.c | 2 -- ext/date/tests/createFromTimestamp.phpt | 26 +++++++++++-------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 9cd5ca04d753f..f69d9abf2681a 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2504,8 +2504,6 @@ PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long se { dateobj->time = timelib_time_ctor(); dateobj->time->zone_type = TIMELIB_ZONETYPE_OFFSET; - dateobj->time->z = (timelib_sll)0; - dateobj->time->have_relative = 0; timelib_unixtime2gmt(dateobj->time, (timelib_sll)sec); timelib_update_ts(dateobj->time, NULL); diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index d5c71ca22f7a9..e42f0c9887537 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -1,5 +1,5 @@ --TEST-- -Tests for DateTime[Immutable]::createFromTimestamp & date_create_[immutable_]_from_timestamp +Tests for DateTime[Immutable]::createFromTimestamp & date_create_[immutable_]from_timestamp --INI-- date.timezone=Europe/London --FILE-- @@ -7,10 +7,6 @@ date.timezone=Europe/London define('MAX_32BIT', 2147483647); define('MIN_32BIT', -2147483648); -define('UMAX_64BIT', 18446744073709551616.0); - -$int = 1696883232; -$float = 1696883232.013981; $timestamps = array( 1696883232, @@ -24,8 +20,8 @@ $timestamps = array( -0.0, MAX_32BIT, MIN_32BIT, - UMAX_64BIT, - -UMAX_64BIT, + PHP_INT_MAX + 1024.0, + PHP_INT_MIN - 1025.0, NAN, +INF, -INF @@ -399,14 +395,14 @@ DateTimeImmutable::createFromTimestamp(-2147483648): object(DateTimeImmutable)#% ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(1.8446744073709552E+19): bool(false) -DateTime::createFromTimestamp(1.8446744073709552E+19): bool(false) -date_create_immutable_from_timestamp(1.8446744073709552E+19): bool(false) -DateTimeImmutable::createFromTimestamp(1.8446744073709552E+19): bool(false) -date_create_from_timestamp(-1.8446744073709552E+19): bool(false) -DateTime::createFromTimestamp(-1.8446744073709552E+19): bool(false) -date_create_immutable_from_timestamp(-1.8446744073709552E+19): bool(false) -DateTimeImmutable::createFromTimestamp(-1.8446744073709552E+19): bool(false) +date_create_from_timestamp(9.223372036854776E+18): bool(false) +DateTime::createFromTimestamp(9.223372036854776E+18): bool(false) +date_create_immutable_from_timestamp(9.223372036854776E+18): bool(false) +DateTimeImmutable::createFromTimestamp(9.223372036854776E+18): bool(false) +date_create_from_timestamp(-9.223372036854778E+18): bool(false) +DateTime::createFromTimestamp(-9.223372036854778E+18): bool(false) +date_create_immutable_from_timestamp(-9.223372036854778E+18): bool(false) +DateTimeImmutable::createFromTimestamp(-9.223372036854778E+18): bool(false) date_create_from_timestamp(NAN): bool(false) DateTime::createFromTimestamp(NAN): bool(false) date_create_immutable_from_timestamp(NAN): bool(false) From c7cc82365ca7d6a887fcac5ca11fb76295d20c3a Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 18 Oct 2023 22:22:36 +0200 Subject: [PATCH 3/5] DateRangeError + static return type --- Zend/Optimizer/zend_func_infos.h | 4 +- ext/date/php_date.c | 49 ++++++++----- ext/date/php_date.stub.php | 8 +- ext/date/php_date_arginfo.h | 12 ++- ext/date/tests/createFromTimestamp.phpt | 97 +++++++++++++++++++------ 5 files changed, 115 insertions(+), 55 deletions(-) diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index 35e28c82307e9..490e0a2b33adc 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -54,8 +54,8 @@ static const func_info_t func_infos[] = { F1("date_create_immutable", MAY_BE_OBJECT|MAY_BE_FALSE), F1("date_create_from_format", MAY_BE_OBJECT|MAY_BE_FALSE), F1("date_create_immutable_from_format", MAY_BE_OBJECT|MAY_BE_FALSE), - F1("date_create_from_timestamp", MAY_BE_OBJECT|MAY_BE_FALSE), - F1("date_create_immutable_from_timestamp", MAY_BE_OBJECT|MAY_BE_FALSE), + F1("date_create_from_timestamp", MAY_BE_OBJECT), + F1("date_create_immutable_from_timestamp", MAY_BE_OBJECT), F1("date_parse", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY), F1("date_parse_from_format", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY), F1("date_get_last_errors", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE), diff --git a/ext/date/php_date.c b/ext/date/php_date.c index f69d9abf2681a..661e8b8d30c6c 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2512,14 +2512,21 @@ PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long se PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) /* {{{ */ { + double sec_dval = trunc(ts); zend_long sec; int usec; - if (UNEXPECTED(isnan(ts) || !ZEND_DOUBLE_FITS_LONG(ts))) { - return 0; + if (UNEXPECTED(isnan(sec_dval) + || sec_dval >= (double)TIMELIB_LONG_MAX + || sec_dval < (double)TIMELIB_LONG_MIN + )) { + zend_throw_error(date_ce_date_range_error, + "Seconds must be a finite number between "TIMELIB_LONG_FMT" and "TIMELIB_LONG_FMT", %g given", + TIMELIB_LONG_MIN, TIMELIB_LONG_MAX, sec_dval); + return false; } - sec = (zend_long)ts; + sec = (zend_long)sec_dval; usec = (int)(fmod(ts, 1) * 1000000); if (UNEXPECTED(usec < 0)) { @@ -2529,7 +2536,7 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) php_date_initialize_from_ts_long(dateobj, sec, usec); - return 1; + return true; } /* }}} */ /* {{{ Returns new DateTime object */ @@ -2621,60 +2628,66 @@ PHP_FUNCTION(date_create_immutable_from_format) /* {{{ Returns new DateTime object from given unix timetamp */ PHP_FUNCTION(date_create_from_timestamp) { - php_date_obj *dateobj; zval *value; + zval new_object; + php_date_obj *new_dateobj; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_NUMBER(value) ZEND_PARSE_PARAMETERS_END(); - php_date_instantiate(date_ce_date, return_value); - dateobj = Z_PHPDATE_P(return_value); + php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, &new_object); + new_dateobj = Z_PHPDATE_P(&new_object); switch (Z_TYPE_P(value)) { case IS_LONG: - php_date_initialize_from_ts_long(dateobj, Z_LVAL_P(value), 0); + php_date_initialize_from_ts_long(new_dateobj, Z_LVAL_P(value), 0); break; case IS_DOUBLE: - if (!php_date_initialize_from_ts_double(dateobj, Z_DVAL_P(value))) { - zval_ptr_dtor(return_value); - RETURN_FALSE; + if (!php_date_initialize_from_ts_double(new_dateobj, Z_DVAL_P(value))) { + zval_ptr_dtor(&new_object); + RETURN_THROWS(); } break; EMPTY_SWITCH_DEFAULT_CASE(); } + + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ /* {{{ Returns new DateTimeImmutable object from given unix timestamp */ PHP_FUNCTION(date_create_immutable_from_timestamp) { - php_date_obj *dateobj; zval *value; + zval new_object; + php_date_obj *new_dateobj; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_NUMBER(value) ZEND_PARSE_PARAMETERS_END(); - php_date_instantiate(date_ce_immutable, return_value); - dateobj = Z_PHPDATE_P(return_value); + php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, &new_object); + new_dateobj = Z_PHPDATE_P(&new_object); switch (Z_TYPE_P(value)) { case IS_LONG: - php_date_initialize_from_ts_long(dateobj, Z_LVAL_P(value), 0); + php_date_initialize_from_ts_long(new_dateobj, Z_LVAL_P(value), 0); break; case IS_DOUBLE: - if (!php_date_initialize_from_ts_double(dateobj, Z_DVAL_P(value))) { - zval_ptr_dtor(return_value); - RETURN_FALSE; + if (!php_date_initialize_from_ts_double(new_dateobj, Z_DVAL_P(value))) { + zval_ptr_dtor(&new_object); + RETURN_THROWS(); } break; EMPTY_SWITCH_DEFAULT_CASE(); } + + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index f12bb4c996fee..e53b704d54d87 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -160,10 +160,10 @@ function date_create_immutable_from_format( string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false {} /** @refcount 1 */ -function date_create_from_timestamp(int|float $timestamp): DateTime|false {} +function date_create_from_timestamp(int|float $timestamp): DateTime {} /** @refcount 1 */ -function date_create_immutable_from_timestamp(int|float $timestamp): DateTimeImmutable|false {} +function date_create_immutable_from_timestamp(int|float $timestamp): DateTimeImmutable {} /** * @return array @@ -372,7 +372,7 @@ public static function createFromFormat(string $format, string $datetime, ?DateT * @tentative-return-type * @alias date_create_from_timestamp */ - public static function createFromTimestamp(int|float $timestamp): DateTime|false {} + public static function createFromTimestamp(int|float $timestamp): static {} /** * @return array|false @@ -482,7 +482,7 @@ public static function createFromFormat(string $format, string $datetime, ?DateT * @tentative-return-type * @alias date_create_immutable_from_timestamp */ - public static function createFromTimestamp(int|float $timestamp): DateTimeImmutable|false {} + public static function createFromTimestamp(int|float $timestamp): static {} /** * @return array|false diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index d2c51f4af9a82..485503838952e 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d4cdf0d730b96add41971f720191db9567bd8180 */ + * Stub hash: c73aefc473674996f63494a7812df9c7e1a5a0fe */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) @@ -76,11 +76,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_immutable_from_f ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_from_timestamp, 0, 1, DateTime, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_date_create_from_timestamp, 0, 1, DateTime, 0) ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_immutable_from_timestamp, 0, 1, DateTimeImmutable, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_date_create_immutable_from_timestamp, 0, 1, DateTimeImmutable, 0) ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_END_ARG_INFO() @@ -288,7 +288,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTime_cre ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTime_createFromTimestamp, 0, 1, DateTime, MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTime_createFromTimestamp, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_END_ARG_INFO() @@ -360,9 +360,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTimeImmu ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTimeImmutable_createFromTimestamp, 0, 1, DateTimeImmutable, MAY_BE_FALSE) - ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) -ZEND_END_ARG_INFO() +#define arginfo_class_DateTimeImmutable_createFromTimestamp arginfo_class_DateTime_createFromTimestamp #define arginfo_class_DateTimeImmutable_getLastErrors arginfo_class_DateTime_getLastErrors diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index e42f0c9887537..725f0da859357 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -5,6 +5,9 @@ date.timezone=Europe/London --FILE-- getMessage() . "\n"; + } echo 'DateTime::createFromTimestamp(' . var_export($ts, true) . '): '; - var_dump(DateTime::createFromTimestamp($ts)); + try { + var_dump(DateTime::createFromTimestamp($ts)); + } catch (Throwable $e) { + echo get_class($e) . ': ' . $e->getMessage() . "\n"; + } echo 'date_create_immutable_from_timestamp(' . var_export($ts, true) . '): '; - var_dump(date_create_immutable_from_timestamp($ts)); + try { + var_dump(date_create_immutable_from_timestamp($ts)); + } catch (Throwable $e) { + echo get_class($e) . ': ' . $e->getMessage() . "\n"; + } echo 'DateTimeImmutable::createFromTimestamp(' . var_export($ts, true) . '): '; - var_dump(DateTimeImmutable::createFromTimestamp($ts)); + try { + var_dump(DateTimeImmutable::createFromTimestamp($ts)); + } catch (Throwable $e) { + echo get_class($e) . ': ' . $e->getMessage() . "\n"; + } +} + +echo 'MyDateTime::createFromTimestamp(' . var_export(0, true) . '): '; +try { + var_dump(MyDateTime::createFromTimestamp(0)); +} catch (Throwable $e) { + echo get_class($e) . ': ' . $e->getMessage() . "\n"; +} + +echo 'MyDateTimeImmutable::createFromTimestamp(' . var_export(0, true) . '): '; +try { + var_dump(MyDateTimeImmutable::createFromTimestamp(0)); +} catch (Throwable $e) { + echo get_class($e) . ': ' . $e->getMessage() . "\n"; } ?> @@ -395,23 +428,39 @@ DateTimeImmutable::createFromTimestamp(-2147483648): object(DateTimeImmutable)#% ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(9.223372036854776E+18): bool(false) -DateTime::createFromTimestamp(9.223372036854776E+18): bool(false) -date_create_immutable_from_timestamp(9.223372036854776E+18): bool(false) -DateTimeImmutable::createFromTimestamp(9.223372036854776E+18): bool(false) -date_create_from_timestamp(-9.223372036854778E+18): bool(false) -DateTime::createFromTimestamp(-9.223372036854778E+18): bool(false) -date_create_immutable_from_timestamp(-9.223372036854778E+18): bool(false) -DateTimeImmutable::createFromTimestamp(-9.223372036854778E+18): bool(false) -date_create_from_timestamp(NAN): bool(false) -DateTime::createFromTimestamp(NAN): bool(false) -date_create_immutable_from_timestamp(NAN): bool(false) -DateTimeImmutable::createFromTimestamp(NAN): bool(false) -date_create_from_timestamp(INF): bool(false) -DateTime::createFromTimestamp(INF): bool(false) -date_create_immutable_from_timestamp(INF): bool(false) -DateTimeImmutable::createFromTimestamp(INF): bool(false) -date_create_from_timestamp(-INF): bool(false) -DateTime::createFromTimestamp(-INF): bool(false) -date_create_immutable_from_timestamp(-INF): bool(false) -DateTimeImmutable::createFromTimestamp(-INF): bool(false) +date_create_from_timestamp(9.223372036854776E+18): DateRangeError: Seconds must be a finite number between %i and %i, 9.22337e+18 given +DateTime::createFromTimestamp(9.223372036854776E+18): DateRangeError: Seconds must be a finite number between %i and %i, 9.22337e+18 given +date_create_immutable_from_timestamp(9.223372036854776E+18): DateRangeError: Seconds must be a finite number between %i and %i, 9.22337e+18 given +DateTimeImmutable::createFromTimestamp(9.223372036854776E+18): DateRangeError: Seconds must be a finite number between %i and %i, 9.22337e+18 given +date_create_from_timestamp(-9.223372036854778E+18): DateRangeError: Seconds must be a finite number between %i and %i, -9.22337e+18 given +DateTime::createFromTimestamp(-9.223372036854778E+18): DateRangeError: Seconds must be a finite number between %i and %i, -9.22337e+18 given +date_create_immutable_from_timestamp(-9.223372036854778E+18): DateRangeError: Seconds must be a finite number between %i and %i, -9.22337e+18 given +DateTimeImmutable::createFromTimestamp(-9.223372036854778E+18): DateRangeError: Seconds must be a finite number between %i and %i, -9.22337e+18 given +date_create_from_timestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given +DateTime::createFromTimestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given +date_create_immutable_from_timestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given +DateTimeImmutable::createFromTimestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given +date_create_from_timestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given +DateTime::createFromTimestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given +date_create_immutable_from_timestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given +DateTimeImmutable::createFromTimestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given +date_create_from_timestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given +DateTime::createFromTimestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given +date_create_immutable_from_timestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given +DateTimeImmutable::createFromTimestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given +MyDateTime::createFromTimestamp(0): object(MyDateTime)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +MyDateTimeImmutable::createFromTimestamp(0): object(MyDateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1970-01-01 00:00:00.000000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} From 178f7ce3dd7a88f3e831e66dc49474c32e347191 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Sat, 28 Oct 2023 15:59:23 +0200 Subject: [PATCH 4/5] Tests should pass 32bit now --- ext/date/tests/createFromTimestamp.phpt | 49 +++++++++++++++++++++---- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index 725f0da859357..2394ce004cea5 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -23,6 +23,7 @@ $timestamps = array( -0.0, MAX_32BIT, MIN_32BIT, + MIN_32BIT - 0.5, PHP_INT_MAX + 1024.0, PHP_INT_MIN - 1025.0, NAN, @@ -428,14 +429,46 @@ DateTimeImmutable::createFromTimestamp(-2147483648): object(DateTimeImmutable)#% ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(9.223372036854776E+18): DateRangeError: Seconds must be a finite number between %i and %i, 9.22337e+18 given -DateTime::createFromTimestamp(9.223372036854776E+18): DateRangeError: Seconds must be a finite number between %i and %i, 9.22337e+18 given -date_create_immutable_from_timestamp(9.223372036854776E+18): DateRangeError: Seconds must be a finite number between %i and %i, 9.22337e+18 given -DateTimeImmutable::createFromTimestamp(9.223372036854776E+18): DateRangeError: Seconds must be a finite number between %i and %i, 9.22337e+18 given -date_create_from_timestamp(-9.223372036854778E+18): DateRangeError: Seconds must be a finite number between %i and %i, -9.22337e+18 given -DateTime::createFromTimestamp(-9.223372036854778E+18): DateRangeError: Seconds must be a finite number between %i and %i, -9.22337e+18 given -date_create_immutable_from_timestamp(-9.223372036854778E+18): DateRangeError: Seconds must be a finite number between %i and %i, -9.22337e+18 given -DateTimeImmutable::createFromTimestamp(-9.223372036854778E+18): DateRangeError: Seconds must be a finite number between %i and %i, -9.22337e+18 given +date_create_from_timestamp(-2147483648.5): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:51.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTime::createFromTimestamp(-2147483648.5): object(DateTime)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:51.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_immutable_from_timestamp(-2147483648.5): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:51.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +DateTimeImmutable::createFromTimestamp(-2147483648.5): object(DateTimeImmutable)#%d (3) { + ["date"]=> + string(26) "1901-12-13 20:45:51.500000" + ["timezone_type"]=> + int(1) + ["timezone"]=> + string(6) "+00:00" +} +date_create_from_timestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given +DateTime::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given +date_create_immutable_from_timestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given +DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given +date_create_from_timestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given +DateTime::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given +date_create_immutable_from_timestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given +DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given date_create_from_timestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given DateTime::createFromTimestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given date_create_immutable_from_timestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given From 759a9e48437bbd1381d203939d134deed1adba81 Mon Sep 17 00:00:00 2001 From: Marc Bennewitz Date: Wed, 8 Nov 2023 22:49:48 +0100 Subject: [PATCH 5/5] Removed fn date_create_[immutable_]from_timestamp as suggested by @derickr --- Zend/Optimizer/zend_func_infos.h | 2 - ext/date/php_date.c | 142 +++++++-------- ext/date/php_date.h | 3 +- ext/date/php_date.stub.php | 16 +- ext/date/php_date_arginfo.h | 20 +-- ext/date/tests/createFromTimestamp.phpt | 218 +----------------------- 6 files changed, 83 insertions(+), 318 deletions(-) diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index 490e0a2b33adc..6dc947e3cc839 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -54,8 +54,6 @@ static const func_info_t func_infos[] = { F1("date_create_immutable", MAY_BE_OBJECT|MAY_BE_FALSE), F1("date_create_from_format", MAY_BE_OBJECT|MAY_BE_FALSE), F1("date_create_immutable_from_format", MAY_BE_OBJECT|MAY_BE_FALSE), - F1("date_create_from_timestamp", MAY_BE_OBJECT), - F1("date_create_immutable_from_timestamp", MAY_BE_OBJECT), F1("date_parse", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY), F1("date_parse_from_format", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY), F1("date_get_last_errors", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE), diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 661e8b8d30c6c..509b09ef37ddd 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2520,9 +2520,13 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) || sec_dval >= (double)TIMELIB_LONG_MAX || sec_dval < (double)TIMELIB_LONG_MIN )) { - zend_throw_error(date_ce_date_range_error, - "Seconds must be a finite number between "TIMELIB_LONG_FMT" and "TIMELIB_LONG_FMT", %g given", - TIMELIB_LONG_MIN, TIMELIB_LONG_MAX, sec_dval); + zend_throw_error( + date_ce_date_range_error, + "Seconds must be a finite number between " TIMELIB_LONG_FMT " and " TIMELIB_LONG_FMT ", %g given", + TIMELIB_LONG_MIN, + TIMELIB_LONG_MAX, + sec_dval + ); return false; } @@ -2625,72 +2629,6 @@ PHP_FUNCTION(date_create_immutable_from_format) } /* }}} */ -/* {{{ Returns new DateTime object from given unix timetamp */ -PHP_FUNCTION(date_create_from_timestamp) -{ - zval *value; - zval new_object; - php_date_obj *new_dateobj; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_NUMBER(value) - ZEND_PARSE_PARAMETERS_END(); - - php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, &new_object); - new_dateobj = Z_PHPDATE_P(&new_object); - - switch (Z_TYPE_P(value)) { - case IS_LONG: - php_date_initialize_from_ts_long(new_dateobj, Z_LVAL_P(value), 0); - break; - - case IS_DOUBLE: - if (!php_date_initialize_from_ts_double(new_dateobj, Z_DVAL_P(value))) { - zval_ptr_dtor(&new_object); - RETURN_THROWS(); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - RETURN_OBJ(Z_OBJ(new_object)); -} -/* }}} */ - -/* {{{ Returns new DateTimeImmutable object from given unix timestamp */ -PHP_FUNCTION(date_create_immutable_from_timestamp) -{ - zval *value; - zval new_object; - php_date_obj *new_dateobj; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_NUMBER(value) - ZEND_PARSE_PARAMETERS_END(); - - php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, &new_object); - new_dateobj = Z_PHPDATE_P(&new_object); - - switch (Z_TYPE_P(value)) { - case IS_LONG: - php_date_initialize_from_ts_long(new_dateobj, Z_LVAL_P(value), 0); - break; - - case IS_DOUBLE: - if (!php_date_initialize_from_ts_double(new_dateobj, Z_DVAL_P(value))) { - zval_ptr_dtor(&new_object); - RETURN_THROWS(); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - RETURN_OBJ(Z_OBJ(new_object)); -} -/* }}} */ - /* {{{ Creates new DateTime object */ PHP_METHOD(DateTime, __construct) { @@ -2767,6 +2705,39 @@ PHP_METHOD(DateTime, createFromInterface) } /* }}} */ +/* {{{ Creates new DateTime object from given unix timetamp */ +PHP_METHOD(DateTime, createFromTimestamp) +{ + zval *value; + zval new_object; + php_date_obj *new_dateobj; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_NUMBER(value) + ZEND_PARSE_PARAMETERS_END(); + + php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, &new_object); + new_dateobj = Z_PHPDATE_P(&new_object); + + switch (Z_TYPE_P(value)) { + case IS_LONG: + php_date_initialize_from_ts_long(new_dateobj, Z_LVAL_P(value), 0); + break; + + case IS_DOUBLE: + if (!php_date_initialize_from_ts_double(new_dateobj, Z_DVAL_P(value))) { + zval_ptr_dtor(&new_object); + RETURN_THROWS(); + } + break; + + EMPTY_SWITCH_DEFAULT_CASE(); + } + + RETURN_OBJ(Z_OBJ(new_object)); +} +/* }}} */ + /* {{{ Creates new DateTimeImmutable object from an existing mutable DateTime object. */ PHP_METHOD(DateTimeImmutable, createFromMutable) { @@ -2809,6 +2780,39 @@ PHP_METHOD(DateTimeImmutable, createFromInterface) } /* }}} */ +/* {{{ Creates new DateTimeImmutable object from given unix timestamp */ +PHP_METHOD(DateTimeImmutable, createFromTimestamp) +{ + zval *value; + zval new_object; + php_date_obj *new_dateobj; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_NUMBER(value) + ZEND_PARSE_PARAMETERS_END(); + + php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, &new_object); + new_dateobj = Z_PHPDATE_P(&new_object); + + switch (Z_TYPE_P(value)) { + case IS_LONG: + php_date_initialize_from_ts_long(new_dateobj, Z_LVAL_P(value), 0); + break; + + case IS_DOUBLE: + if (!php_date_initialize_from_ts_double(new_dateobj, Z_DVAL_P(value))) { + zval_ptr_dtor(&new_object); + RETURN_THROWS(); + } + break; + + EMPTY_SWITCH_DEFAULT_CASE(); + } + + RETURN_OBJ(Z_OBJ(new_object)); +} +/* }}} */ + static bool php_date_initialize_from_hash(php_date_obj **dateobj, HashTable *myht) { zval *z_date; diff --git a/ext/date/php_date.h b/ext/date/php_date.h index a4729ff58ffeb..a67564476bec7 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -142,6 +142,7 @@ PHPAPI zend_class_entry *php_date_get_period_ce(void); PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object); PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags); - +PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec); +PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts); #endif /* PHP_DATE_H */ diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index e53b704d54d87..7ba05b8b6e062 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -159,12 +159,6 @@ function date_create_from_format( function date_create_immutable_from_format( string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false {} -/** @refcount 1 */ -function date_create_from_timestamp(int|float $timestamp): DateTime {} - -/** @refcount 1 */ -function date_create_immutable_from_timestamp(int|float $timestamp): DateTimeImmutable {} - /** * @return array * @refcount 1 @@ -368,10 +362,7 @@ public static function createFromInterface(DateTimeInterface $object): DateTime */ public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false {} - /** - * @tentative-return-type - * @alias date_create_from_timestamp - */ + /** @tentative-return-type */ public static function createFromTimestamp(int|float $timestamp): static {} /** @@ -478,10 +469,7 @@ public static function __set_state(array $array): DateTimeImmutable {} */ public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false {} - /** - * @tentative-return-type - * @alias date_create_immutable_from_timestamp - */ + /** @tentative-return-type */ public static function createFromTimestamp(int|float $timestamp): static {} /** diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index 485503838952e..027bec67cb08d 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c73aefc473674996f63494a7812df9c7e1a5a0fe */ + * Stub hash: 1445f6053da5ca9dc7bb618f2eadc4a8ea56a15f */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) @@ -76,14 +76,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_immutable_from_f ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_date_create_from_timestamp, 0, 1, DateTime, 0) - ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_date_create_immutable_from_timestamp, 0, 1, DateTimeImmutable, 0) - ZEND_ARG_TYPE_MASK(0, timestamp, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_date_parse, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -529,8 +521,6 @@ ZEND_FUNCTION(date_create); ZEND_FUNCTION(date_create_immutable); ZEND_FUNCTION(date_create_from_format); ZEND_FUNCTION(date_create_immutable_from_format); -ZEND_FUNCTION(date_create_from_timestamp); -ZEND_FUNCTION(date_create_immutable_from_timestamp); ZEND_FUNCTION(date_parse); ZEND_FUNCTION(date_parse_from_format); ZEND_FUNCTION(date_get_last_errors); @@ -570,6 +560,7 @@ ZEND_METHOD(DateTime, __wakeup); ZEND_METHOD(DateTime, __set_state); ZEND_METHOD(DateTime, createFromImmutable); ZEND_METHOD(DateTime, createFromInterface); +ZEND_METHOD(DateTime, createFromTimestamp); ZEND_METHOD(DateTime, modify); ZEND_METHOD(DateTime, sub); ZEND_METHOD(DateTimeImmutable, __construct); @@ -577,6 +568,7 @@ ZEND_METHOD(DateTimeImmutable, __serialize); ZEND_METHOD(DateTimeImmutable, __unserialize); ZEND_METHOD(DateTimeImmutable, __wakeup); ZEND_METHOD(DateTimeImmutable, __set_state); +ZEND_METHOD(DateTimeImmutable, createFromTimestamp); ZEND_METHOD(DateTimeImmutable, modify); ZEND_METHOD(DateTimeImmutable, add); ZEND_METHOD(DateTimeImmutable, sub); @@ -628,8 +620,6 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(date_create_immutable, arginfo_date_create_immutable) ZEND_FE(date_create_from_format, arginfo_date_create_from_format) ZEND_FE(date_create_immutable_from_format, arginfo_date_create_immutable_from_format) - ZEND_FE(date_create_from_timestamp, arginfo_date_create_from_timestamp) - ZEND_FE(date_create_immutable_from_timestamp, arginfo_date_create_immutable_from_timestamp) ZEND_FE(date_parse, arginfo_date_parse) ZEND_FE(date_parse_from_format, arginfo_date_parse_from_format) ZEND_FE(date_get_last_errors, arginfo_date_get_last_errors) @@ -688,7 +678,7 @@ static const zend_function_entry class_DateTime_methods[] = { ZEND_ME(DateTime, createFromImmutable, arginfo_class_DateTime_createFromImmutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(DateTime, createFromInterface, arginfo_class_DateTime_createFromInterface, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(createFromFormat, date_create_from_format, arginfo_class_DateTime_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - ZEND_ME_MAPPING(createFromTimestamp, date_create_from_timestamp, arginfo_class_DateTime_createFromTimestamp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(DateTime, createFromTimestamp, arginfo_class_DateTime_createFromTimestamp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_class_DateTime_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(format, date_format, arginfo_class_DateTime_format, ZEND_ACC_PUBLIC) ZEND_ME(DateTime, modify, arginfo_class_DateTime_modify, ZEND_ACC_PUBLIC) @@ -714,7 +704,7 @@ static const zend_function_entry class_DateTimeImmutable_methods[] = { ZEND_ME(DateTimeImmutable, __wakeup, arginfo_class_DateTimeImmutable___wakeup, ZEND_ACC_PUBLIC) ZEND_ME(DateTimeImmutable, __set_state, arginfo_class_DateTimeImmutable___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(createFromFormat, date_create_immutable_from_format, arginfo_class_DateTimeImmutable_createFromFormat, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - ZEND_ME_MAPPING(createFromTimestamp, date_create_immutable_from_timestamp, arginfo_class_DateTimeImmutable_createFromTimestamp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(DateTimeImmutable, createFromTimestamp, arginfo_class_DateTimeImmutable_createFromTimestamp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_class_DateTimeImmutable_getLastErrors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME_MAPPING(format, date_format, arginfo_class_DateTimeImmutable_format, ZEND_ACC_PUBLIC) ZEND_ME_MAPPING(getTimezone, date_timezone_get, arginfo_class_DateTimeImmutable_getTimezone, ZEND_ACC_PUBLIC) diff --git a/ext/date/tests/createFromTimestamp.phpt b/ext/date/tests/createFromTimestamp.phpt index 2394ce004cea5..7e27e19941beb 100644 --- a/ext/date/tests/createFromTimestamp.phpt +++ b/ext/date/tests/createFromTimestamp.phpt @@ -1,5 +1,5 @@ --TEST-- -Tests for DateTime[Immutable]::createFromTimestamp & date_create_[immutable_]from_timestamp +Tests for DateTime[Immutable]::createFromTimestamp --INI-- date.timezone=Europe/London --FILE-- @@ -32,13 +32,6 @@ $timestamps = array( ); foreach ($timestamps as $ts) { - echo 'date_create_from_timestamp(' . var_export($ts, true) . '): '; - try { - var_dump(date_create_from_timestamp($ts)); - } catch (Throwable $e) { - echo get_class($e) . ': ' . $e->getMessage() . "\n"; - } - echo 'DateTime::createFromTimestamp(' . var_export($ts, true) . '): '; try { var_dump(DateTime::createFromTimestamp($ts)); @@ -46,13 +39,6 @@ foreach ($timestamps as $ts) { echo get_class($e) . ': ' . $e->getMessage() . "\n"; } - echo 'date_create_immutable_from_timestamp(' . var_export($ts, true) . '): '; - try { - var_dump(date_create_immutable_from_timestamp($ts)); - } catch (Throwable $e) { - echo get_class($e) . ': ' . $e->getMessage() . "\n"; - } - echo 'DateTimeImmutable::createFromTimestamp(' . var_export($ts, true) . '): '; try { var_dump(DateTimeImmutable::createFromTimestamp($ts)); @@ -77,14 +63,6 @@ try { ?> --EXPECTF-- -date_create_from_timestamp(1696883232): object(DateTime)#%d (3) { - ["date"]=> - string(26) "2023-10-09 20:27:12.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(1696883232): object(DateTime)#%d (3) { ["date"]=> string(26) "2023-10-09 20:27:12.000000" @@ -93,14 +71,6 @@ DateTime::createFromTimestamp(1696883232): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(1696883232): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "2023-10-09 20:27:12.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(1696883232): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "2023-10-09 20:27:12.000000" @@ -109,14 +79,6 @@ DateTimeImmutable::createFromTimestamp(1696883232): object(DateTimeImmutable)#%d ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(-1696883232): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1916-03-25 03:32:48.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(-1696883232): object(DateTime)#%d (3) { ["date"]=> string(26) "1916-03-25 03:32:48.000000" @@ -125,14 +87,6 @@ DateTime::createFromTimestamp(-1696883232): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(-1696883232): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1916-03-25 03:32:48.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(-1696883232): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1916-03-25 03:32:48.000000" @@ -141,14 +95,6 @@ DateTimeImmutable::createFromTimestamp(-1696883232): object(DateTimeImmutable)#% ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(1696883232.013981): object(DateTime)#%d (3) { - ["date"]=> - string(26) "2023-10-09 20:27:12.013981" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(1696883232.013981): object(DateTime)#%d (3) { ["date"]=> string(26) "2023-10-09 20:27:12.013981" @@ -157,14 +103,6 @@ DateTime::createFromTimestamp(1696883232.013981): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(1696883232.013981): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "2023-10-09 20:27:12.013981" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(1696883232.013981): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "2023-10-09 20:27:12.013981" @@ -173,14 +111,6 @@ DateTimeImmutable::createFromTimestamp(1696883232.013981): object(DateTimeImmuta ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(-1696883232.013981): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1916-03-25 03:32:47.986019" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(-1696883232.013981): object(DateTime)#%d (3) { ["date"]=> string(26) "1916-03-25 03:32:47.986019" @@ -189,14 +119,6 @@ DateTime::createFromTimestamp(-1696883232.013981): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(-1696883232.013981): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1916-03-25 03:32:47.986019" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(-1696883232.013981): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1916-03-25 03:32:47.986019" @@ -205,14 +127,6 @@ DateTimeImmutable::createFromTimestamp(-1696883232.013981): object(DateTimeImmut ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(0.123456): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1970-01-01 00:00:00.123456" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(0.123456): object(DateTime)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.123456" @@ -221,14 +135,6 @@ DateTime::createFromTimestamp(0.123456): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(0.123456): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1970-01-01 00:00:00.123456" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(0.123456): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.123456" @@ -237,14 +143,6 @@ DateTimeImmutable::createFromTimestamp(0.123456): object(DateTimeImmutable)#%d ( ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(-0.123456): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1969-12-31 23:59:59.876544" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(-0.123456): object(DateTime)#%d (3) { ["date"]=> string(26) "1969-12-31 23:59:59.876544" @@ -253,14 +151,6 @@ DateTime::createFromTimestamp(-0.123456): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(-0.123456): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1969-12-31 23:59:59.876544" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(-0.123456): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1969-12-31 23:59:59.876544" @@ -269,14 +159,6 @@ DateTimeImmutable::createFromTimestamp(-0.123456): object(DateTimeImmutable)#%d ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(0): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1970-01-01 00:00:00.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(0): object(DateTime)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" @@ -285,14 +167,6 @@ DateTime::createFromTimestamp(0): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(0): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1970-01-01 00:00:00.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(0): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" @@ -301,14 +175,6 @@ DateTimeImmutable::createFromTimestamp(0): object(DateTimeImmutable)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(0.0): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1970-01-01 00:00:00.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(0.0): object(DateTime)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" @@ -317,14 +183,6 @@ DateTime::createFromTimestamp(0.0): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(0.0): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1970-01-01 00:00:00.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(0.0): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" @@ -333,14 +191,6 @@ DateTimeImmutable::createFromTimestamp(0.0): object(DateTimeImmutable)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(-0.0): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1970-01-01 00:00:00.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(-0.0): object(DateTime)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" @@ -349,14 +199,6 @@ DateTime::createFromTimestamp(-0.0): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(-0.0): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1970-01-01 00:00:00.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(-0.0): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1970-01-01 00:00:00.000000" @@ -365,14 +207,6 @@ DateTimeImmutable::createFromTimestamp(-0.0): object(DateTimeImmutable)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(2147483647): object(DateTime)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:07.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(2147483647): object(DateTime)#%d (3) { ["date"]=> string(26) "2038-01-19 03:14:07.000000" @@ -381,14 +215,6 @@ DateTime::createFromTimestamp(2147483647): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(2147483647): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "2038-01-19 03:14:07.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(2147483647): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "2038-01-19 03:14:07.000000" @@ -397,14 +223,6 @@ DateTimeImmutable::createFromTimestamp(2147483647): object(DateTimeImmutable)#%d ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(-2147483648): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:52.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(-2147483648): object(DateTime)#%d (3) { ["date"]=> string(26) "1901-12-13 20:45:52.000000" @@ -413,14 +231,6 @@ DateTime::createFromTimestamp(-2147483648): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(-2147483648): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:52.000000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(-2147483648): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1901-12-13 20:45:52.000000" @@ -429,14 +239,6 @@ DateTimeImmutable::createFromTimestamp(-2147483648): object(DateTimeImmutable)#% ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(-2147483648.5): object(DateTime)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:51.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTime::createFromTimestamp(-2147483648.5): object(DateTime)#%d (3) { ["date"]=> string(26) "1901-12-13 20:45:51.500000" @@ -445,14 +247,6 @@ DateTime::createFromTimestamp(-2147483648.5): object(DateTime)#%d (3) { ["timezone"]=> string(6) "+00:00" } -date_create_immutable_from_timestamp(-2147483648.5): object(DateTimeImmutable)#%d (3) { - ["date"]=> - string(26) "1901-12-13 20:45:51.500000" - ["timezone_type"]=> - int(1) - ["timezone"]=> - string(6) "+00:00" -} DateTimeImmutable::createFromTimestamp(-2147483648.5): object(DateTimeImmutable)#%d (3) { ["date"]=> string(26) "1901-12-13 20:45:51.500000" @@ -461,25 +255,15 @@ DateTimeImmutable::createFromTimestamp(-2147483648.5): object(DateTimeImmutable) ["timezone"]=> string(6) "+00:00" } -date_create_from_timestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given DateTime::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given -date_create_immutable_from_timestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given -date_create_from_timestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given DateTime::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given -date_create_immutable_from_timestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given DateTimeImmutable::createFromTimestamp(%f): DateRangeError: Seconds must be a finite number between %i and %i, %f given -date_create_from_timestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given DateTime::createFromTimestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given -date_create_immutable_from_timestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given DateTimeImmutable::createFromTimestamp(NAN): DateRangeError: Seconds must be a finite number between %i and %i, NAN given -date_create_from_timestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given DateTime::createFromTimestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given -date_create_immutable_from_timestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given DateTimeImmutable::createFromTimestamp(INF): DateRangeError: Seconds must be a finite number between %i and %i, INF given -date_create_from_timestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given DateTime::createFromTimestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given -date_create_immutable_from_timestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given DateTimeImmutable::createFromTimestamp(-INF): DateRangeError: Seconds must be a finite number between %i and %i, -INF given MyDateTime::createFromTimestamp(0): object(MyDateTime)#%d (3) { ["date"]=>