Skip to content

Commit 066f041

Browse files
committed
better error message
ext/intl: Allow numeric-castable objects as date/time values in IntlDateFormatter::formatObject() add exception catch, dtor pointers and fix CI use EG to guard fix CI
1 parent e5fa4ec commit 066f041

5 files changed

Lines changed: 54 additions & 6 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::format() 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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ 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::format() now accepts objects that support numeric
205+
casting as date/time values.
206+
203207
- mysqli:
204208
. The return structure of mysqli_get_charset() no longer contains
205209
the undocumented "comment" element. The value of "charsetnr" is

ext/intl/common/common_date.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,28 @@ 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 (EG(exception)) {
210+
} else if (Z_TYPE(casted) == IS_LONG) {
211+
rv = U_MILLIS_PER_SECOND * (double)Z_LVAL(casted);
212+
} else if (Z_TYPE(casted) == IS_DOUBLE) {
213+
rv = U_MILLIS_PER_SECOND * Z_DVAL(casted);
214+
} else {
215+
intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
216+
"invalid object type for date/time "
217+
"(IntlCalendar, DateTimeInterface, or numeric-castable object permitted)");
218+
}
219+
} else if (!EG(exception)) {
220+
intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
221+
"invalid object type for date/time "
222+
"(IntlCalendar, DateTimeInterface, or numeric-castable object permitted)");
223+
}
224+
if (!Z_ISUNDEF(casted)) {
225+
zval_ptr_dtor(&casted);
226+
}
209227
}
210228
break;
211229
case IS_REFERENCE:
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
IntlDateFormatter->format(): 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+
$fmt = new IntlDateFormatter('en_US', IntlDateFormatter::NONE, IntlDateFormatter::NONE, 'UTC', null, 'yyyy-MM-dd HH:mm:ss.SSS');
13+
14+
echo $fmt->format(new NumericCastableNoOperations(0)), "\n";
15+
echo datefmt_format($fmt, new NumericCastableNoOperations(0.5)), "\n";
16+
var_dump($fmt->format(new stdClass()));
17+
var_dump(intl_get_error_message());
18+
19+
?>
20+
--EXPECT--
21+
1970-01-01 00:00:00.000
22+
1970-01-01 00:00:00.500
23+
bool(false)
24+
string(160) "IntlDateFormatter::format(): invalid object type for date/time (IntlCalendar, DateTimeInterface, or numeric-castable object permitted): U_ILLEGAL_ARGUMENT_ERROR"

ext/intl/tests/dateformat_format_error.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ var_dump(intl_get_error_message());
2121
?>
2222
--EXPECT--
2323
bool(false)
24-
string(140) "IntlDateFormatter::format(): invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR"
24+
string(160) "IntlDateFormatter::format(): invalid object type for date/time (IntlCalendar, DateTimeInterface, or numeric-castable object permitted): U_ILLEGAL_ARGUMENT_ERROR"
2525
bool(false)
26-
string(129) "datefmt_format(): invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR"
26+
string(149) "datefmt_format(): invalid object type for date/time (IntlCalendar, DateTimeInterface, or numeric-castable object permitted): U_ILLEGAL_ARGUMENT_ERROR"

0 commit comments

Comments
 (0)