Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cc1144d

Browse files
committed
[Clock] Polyfill DateTimeImmutable::createFromTimestamp()
1 parent 4b659cb commit cc1144d

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/Symfony/Component/Clock/DatePoint.php

+27
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,33 @@ 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)) {
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 (0 <= $timestamp) {
84+
return static::createFromFormat('U.u', sprintf('%.6F', $timestamp));
85+
}
86+
87+
$microsecond = 1_000_000 - (int) (((int) $timestamp - $timestamp) * 1_000_000);
88+
if (1_000_000 === $microsecond) {
89+
$microsecond = 0;
90+
}
91+
92+
return static::createFromFormat('U', (string) (int) floor($timestamp))
93+
->setMicrosecond($microsecond);
94+
}
95+
6996
public function add(\DateInterval $interval): static
7097
{
7198
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)