Skip to content

Commit a8b8a69

Browse files
committed
Fixed a problem where usec was carry up
If round to the fractional part of a timestamp, a carry will occur in cases such as 999 999 9. In that case, set usec to 0 and add 1 to sec.
1 parent 6c034ee commit a8b8a69

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

ext/date/php_date.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,6 +2540,11 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts)
25402540
sec = (zend_long)sec_dval;
25412541
usec = (int) round(fmod(ts, 1) * 1000000);
25422542

2543+
if (UNEXPECTED(usec >= 1000000)) {
2544+
sec++;
2545+
usec = 0;
2546+
}
2547+
25432548
if (UNEXPECTED(usec < 0)) {
25442549
if (UNEXPECTED(sec == TIMELIB_LONG_MIN)) {
25452550
zend_argument_error(

ext/date/tests/gh14383.phpt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
Bug GH-14383 (DateTime::createFromTimestamp overflowed microseconds value)
3+
--INI--
4+
date.timezone=UTC
5+
--FILE--
6+
<?php
7+
$cases = [
8+
[0.999_999_0, '0.999_999_0'],
9+
[0.999_999_1, '0.999_999_1'],
10+
[0.999_999_8, '0.999_999_8'],
11+
[0.999_999_9, '0.999_999_9'],
12+
[1.000_000_0, '1.000_000_0'],
13+
[1.000_000_1, '1.000_000_1'],
14+
[1.000_000_8, '1.000_000_8'],
15+
[1.000_000_9, '1.000_000_9'],
16+
[1.000_001_0, '1.000_001_0'],
17+
[1.000_001_1, '1.000_001_0'],
18+
[1.000_001_8, '1.000_001_8'],
19+
[1.000_001_9, '1.000_001_9'],
20+
];
21+
22+
foreach ($cases as [$usec, $label]) {
23+
echo "{$label}: ";
24+
echo DateTime::createFromTimestamp($usec)->format('s.u'), "\n";
25+
}
26+
?>
27+
--EXPECT--
28+
0.999_999_0: 00.999999
29+
0.999_999_1: 00.999999
30+
0.999_999_8: 01.000000
31+
0.999_999_9: 01.000000
32+
1.000_000_0: 01.000000
33+
1.000_000_1: 01.000000
34+
1.000_000_8: 01.000001
35+
1.000_000_9: 01.000001
36+
1.000_001_0: 01.000001
37+
1.000_001_0: 01.000001
38+
1.000_001_8: 01.000002
39+
1.000_001_9: 01.000002

0 commit comments

Comments
 (0)