Skip to content

Commit b16f89e

Browse files
committed
ext/intl: Allow numeric-castable objects as date/time values in IntlDateFormatter::formatObject()
1 parent e5fa4ec commit b16f89e

4 files changed

Lines changed: 44 additions & 4 deletions

File tree

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ PHP NEWS
6262
. Fixed bug GH-20426 (Spoofchecker::setRestrictionLevel() error message
6363
suggests missing constants). (DanielEScherzer)
6464
. Added grapheme_strrev (Yuya Hamada)
65+
. IntlDateFormatter::formatObject() now accepts numeric-castable objects as
66+
date/time values. (Weilin Du)
6567

6668
- JSON:
6769
. Enriched JSON last error / exception message with error location.

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ PHP 8.6 UPGRADE NOTES
200200
. gmp_powm() modulo-by-zero now raises a DivisionByZeroError whose
201201
message includes the function name and argument index ($modulus).
202202

203+
- Intl:
204+
. IntlDateFormatter::formatObject() now accepts objects that support
205+
numeric casting as date/time values, in addition to IntlCalendar and
206+
DateTimeInterface instances.
207+
203208
- mysqli:
204209
. The return structure of mysqli_get_charset() no longer contains
205210
the undocumented "comment" element. The value of "charsetnr" is

ext/intl/common/common_date.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,23 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err)
202202
}
203203
}
204204
} else {
205-
/* TODO: try with cast(), get() to obtain a number */
206-
intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
207-
"invalid object type for date/time "
208-
"(only IntlCalendar and DateTimeInterface permitted)");
205+
zval casted;
206+
ZVAL_UNDEF(&casted);
207+
208+
if (Z_OBJ_HT_P(z)->cast_object(Z_OBJ_P(z), &casted, _IS_NUMBER) == SUCCESS) {
209+
if (Z_TYPE(casted) == IS_LONG) {
210+
rv = U_MILLIS_PER_SECOND * (double)Z_LVAL(casted);
211+
} else if (Z_TYPE(casted) == IS_DOUBLE) {
212+
rv = U_MILLIS_PER_SECOND * Z_DVAL(casted);
213+
} else {
214+
intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
215+
"invalid object type for date/time");
216+
}
217+
zval_ptr_dtor(&casted);
218+
} else {
219+
intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
220+
"invalid object type for date/time ");
221+
}
209222
}
210223
break;
211224
case IS_REFERENCE:
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
IntlDateFormatter::formatObject(): numeric-castable objects
3+
--EXTENSIONS--
4+
intl
5+
zend_test
6+
--INI--
7+
intl.default_locale=en_US
8+
date.timezone=UTC
9+
--FILE--
10+
<?php
11+
12+
$format = 'yyyy-MM-dd HH:mm:ss.SSS';
13+
14+
echo IntlDateFormatter::formatObject(new NumericCastableNoOperations(0), $format, 'en_US'), "\n";
15+
echo IntlDateFormatter::formatObject(new NumericCastableNoOperations(0.5), $format, 'en_US'), "\n";
16+
17+
?>
18+
--EXPECT--
19+
1970-01-01 00:00:00.000
20+
1970-01-01 00:00:00.500

0 commit comments

Comments
 (0)