diff --git a/NEWS b/NEWS index 4ace7d3dc462..756fd78bb8ac 100644 --- a/NEWS +++ b/NEWS @@ -62,6 +62,8 @@ PHP NEWS . Fixed bug GH-20426 (Spoofchecker::setRestrictionLevel() error message suggests missing constants). (DanielEScherzer) . Added grapheme_strrev (Yuya Hamada) + . IntlDateFormatter::format() now accepts numeric-castable objects as + date/time values. (Weilin Du) - JSON: . Enriched JSON last error / exception message with error location. diff --git a/UPGRADING b/UPGRADING index d271eb47f7d1..297654e7235a 100644 --- a/UPGRADING +++ b/UPGRADING @@ -200,6 +200,10 @@ PHP 8.6 UPGRADE NOTES . gmp_powm() modulo-by-zero now raises a DivisionByZeroError whose message includes the function name and argument index ($modulus). +- Intl: + . IntlDateFormatter::format() now accepts objects that support numeric + casting as date/time values. + - mysqli: . The return structure of mysqli_get_charset() no longer contains the undocumented "comment" element. The value of "charsetnr" is diff --git a/ext/intl/common/common_date.cpp b/ext/intl/common/common_date.cpp index 0a7aa023b43c..36f0cd18a9c3 100644 --- a/ext/intl/common/common_date.cpp +++ b/ext/intl/common/common_date.cpp @@ -202,10 +202,28 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err) } } } else { - /* TODO: try with cast(), get() to obtain a number */ - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - "invalid object type for date/time " - "(only IntlCalendar and DateTimeInterface permitted)"); + zval casted; + ZVAL_UNDEF(&casted); + + if (Z_OBJ_HT_P(z)->cast_object(Z_OBJ_P(z), &casted, _IS_NUMBER) == SUCCESS) { + if (EG(exception)) { + } else if (Z_TYPE(casted) == IS_LONG) { + rv = U_MILLIS_PER_SECOND * (double)Z_LVAL(casted); + } else if (Z_TYPE(casted) == IS_DOUBLE) { + rv = U_MILLIS_PER_SECOND * Z_DVAL(casted); + } else { + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, + "invalid object type for date/time " + "(IntlCalendar, DateTimeInterface, or numeric-castable object permitted)"); + } + } else if (!EG(exception)) { + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, + "invalid object type for date/time " + "(IntlCalendar, DateTimeInterface, or numeric-castable object permitted)"); + } + if (!Z_ISUNDEF(casted)) { + zval_ptr_dtor(&casted); + } } break; case IS_REFERENCE: diff --git a/ext/intl/tests/dateformat_formatObject_numeric_object.phpt b/ext/intl/tests/dateformat_formatObject_numeric_object.phpt new file mode 100644 index 000000000000..b2a9a02f6bc8 --- /dev/null +++ b/ext/intl/tests/dateformat_formatObject_numeric_object.phpt @@ -0,0 +1,24 @@ +--TEST-- +IntlDateFormatter->format(): numeric-castable objects +--EXTENSIONS-- +intl +zend_test +--INI-- +intl.default_locale=en_US +date.timezone=UTC +--FILE-- +format(new NumericCastableNoOperations(0)), "\n"; +echo datefmt_format($fmt, new NumericCastableNoOperations(0.5)), "\n"; +var_dump($fmt->format(new stdClass())); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +1970-01-01 00:00:00.000 +1970-01-01 00:00:00.500 +bool(false) +string(160) "IntlDateFormatter::format(): invalid object type for date/time (IntlCalendar, DateTimeInterface, or numeric-castable object permitted): U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_format_error.phpt b/ext/intl/tests/dateformat_format_error.phpt index 4358271efd08..f83f8250143e 100644 --- a/ext/intl/tests/dateformat_format_error.phpt +++ b/ext/intl/tests/dateformat_format_error.phpt @@ -21,6 +21,6 @@ var_dump(intl_get_error_message()); ?> --EXPECT-- bool(false) -string(140) "IntlDateFormatter::format(): invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR" +string(160) "IntlDateFormatter::format(): invalid object type for date/time (IntlCalendar, DateTimeInterface, or numeric-castable object permitted): U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(129) "datefmt_format(): invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR" +string(149) "datefmt_format(): invalid object type for date/time (IntlCalendar, DateTimeInterface, or numeric-castable object permitted): U_ILLEGAL_ARGUMENT_ERROR"