Skip to content

Commit a8c43b6

Browse files
feature #54442 [Clock] Add a polyfill for DateTimeImmutable::createFromTimestamp() (derrabus)
This PR was merged into the 7.1 branch. Discussion ---------- [Clock] Add a polyfill for DateTimeImmutable::createFromTimestamp() | Q | A | ------------- | --- | Branch? | 7.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | N/A | License | MIT This PR adds the new `createFromTimestamp()` method introduced in php/php-src#12413 to our `DatePoint` class. It comes with a polyfill implementation for PHP 8.2/8.3. Commits ------- 9e48e0d [Clock] Polyfill DateTimeImmutable::createFromTimestamp()
2 parents 44e4699 + 9e48e0d commit a8c43b6

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/Symfony/Component/Clock/DatePoint.php

+21
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,27 @@ public static function createFromMutable(\DateTime $object): static
6666
return parent::createFromMutable($object);
6767
}
6868

69+
public static function createFromTimestamp(int|float $timestamp): static
70+
{
71+
if (\PHP_VERSION_ID >= 80400) {
72+
return parent::createFromTimestamp($timestamp);
73+
}
74+
75+
if (\is_int($timestamp) || !$ms = (int) $timestamp - $timestamp) {
76+
return static::createFromFormat('U', (string) $timestamp);
77+
}
78+
79+
if (!is_finite($timestamp) || \PHP_INT_MAX + 1.0 <= $timestamp || \PHP_INT_MIN > $timestamp) {
80+
throw new \DateRangeError(sprintf('DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between %s and %s.999999, %s given', \PHP_INT_MIN, \PHP_INT_MAX, $timestamp));
81+
}
82+
83+
if ($timestamp < 0) {
84+
$timestamp = (int) $timestamp - 2.0 + $ms;
85+
}
86+
87+
return static::createFromFormat('U.u', sprintf('%.6F', $timestamp));
88+
}
89+
6990
public function add(\DateInterval $interval): static
7091
{
7192
return parent::add($interval);

src/Symfony/Component/Clock/Tests/DatePointTest.php

+41
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,47 @@ public function testCreateFromFormat()
4545
DatePoint::createFromFormat('Y-m-d H:i:s', 'Bad Date');
4646
}
4747

48+
/**
49+
* @dataProvider provideValidTimestamps
50+
*/
51+
public function testCreateFromTimestamp(int|float $timestamp, string $expected)
52+
{
53+
$date = DatePoint::createFromTimestamp($timestamp);
54+
55+
$this->assertInstanceOf(DatePoint::class, $date);
56+
$this->assertSame($expected, $date->format('Y-m-d\TH:i:s.uP'));
57+
}
58+
59+
public static function provideValidTimestamps(): iterable
60+
{
61+
yield 'positive integer' => [1359188516, '2013-01-26T08:21:56.000000+00:00'];
62+
yield 'positive float' => [1359188516.123456, '2013-01-26T08:21:56.123456+00:00'];
63+
yield 'positive integer-ish float' => [1359188516.0, '2013-01-26T08:21:56.000000+00:00'];
64+
yield 'zero as integer' => [0, '1970-01-01T00:00:00.000000+00:00'];
65+
yield 'zero as float' => [0.0, '1970-01-01T00:00:00.000000+00:00'];
66+
yield 'negative integer' => [-100, '1969-12-31T23:58:20.000000+00:00'];
67+
yield 'negative float' => [-100.123456, '1969-12-31T23:58:19.876544+00:00'];
68+
yield 'negative integer-ish float' => [-100.0, '1969-12-31T23:58:20.000000+00:00'];
69+
}
70+
71+
/**
72+
* @dataProvider provideOutOfRangeFloatTimestamps
73+
*/
74+
public function testCreateFromTimestampWithFloatOutOfRange(float $timestamp)
75+
{
76+
$this->expectException(\DateRangeError::class);
77+
$this->expectExceptionMessage('DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between');
78+
DatePoint::createFromTimestamp($timestamp);
79+
}
80+
81+
public static function provideOutOfRangeFloatTimestamps(): iterable
82+
{
83+
yield 'too large (positive)' => [1e20];
84+
yield 'too large (negative)' => [-1e20];
85+
yield 'NaN' => [\NAN];
86+
yield 'infinity' => [\INF];
87+
}
88+
4889
public function testModify()
4990
{
5091
$date = new DatePoint('2010-01-28 15:00:00');

0 commit comments

Comments
 (0)