Skip to content

Commit

Permalink
[Clock] Polyfill DateTimeImmutable::createFromTimestamp()
Browse files Browse the repository at this point in the history
  • Loading branch information
derrabus committed Apr 9, 2024
1 parent 44e4699 commit 9e48e0d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/Symfony/Component/Clock/DatePoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@ public static function createFromMutable(\DateTime $object): static
return parent::createFromMutable($object);
}

public static function createFromTimestamp(int|float $timestamp): static
{
if (\PHP_VERSION_ID >= 80400) {
return parent::createFromTimestamp($timestamp);

Check failure on line 72 in src/Symfony/Component/Clock/DatePoint.php

View workflow job for this annotation

GitHub Actions / Psalm

UndefinedMethod

src/Symfony/Component/Clock/DatePoint.php:72:20: UndefinedMethod: Method DateTimeImmutable::createfromtimestamp does not exist (see https://psalm.dev/022)

Check failure on line 72 in src/Symfony/Component/Clock/DatePoint.php

View workflow job for this annotation

GitHub Actions / Psalm

UndefinedMethod

src/Symfony/Component/Clock/DatePoint.php:72:20: UndefinedMethod: Method DateTimeImmutable::createfromtimestamp does not exist (see https://psalm.dev/022)
}

if (\is_int($timestamp) || !$ms = (int) $timestamp - $timestamp) {
return static::createFromFormat('U', (string) $timestamp);
}

if (!is_finite($timestamp) || \PHP_INT_MAX + 1.0 <= $timestamp || \PHP_INT_MIN > $timestamp) {
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));
}

if ($timestamp < 0) {
$timestamp = (int) $timestamp - 2.0 + $ms;
}

return static::createFromFormat('U.u', sprintf('%.6F', $timestamp));
}

public function add(\DateInterval $interval): static
{
return parent::add($interval);
Expand Down
41 changes: 41 additions & 0 deletions src/Symfony/Component/Clock/Tests/DatePointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,47 @@ public function testCreateFromFormat()
DatePoint::createFromFormat('Y-m-d H:i:s', 'Bad Date');
}

/**
* @dataProvider provideValidTimestamps
*/
public function testCreateFromTimestamp(int|float $timestamp, string $expected)
{
$date = DatePoint::createFromTimestamp($timestamp);

$this->assertInstanceOf(DatePoint::class, $date);
$this->assertSame($expected, $date->format('Y-m-d\TH:i:s.uP'));
}

public static function provideValidTimestamps(): iterable
{
yield 'positive integer' => [1359188516, '2013-01-26T08:21:56.000000+00:00'];
yield 'positive float' => [1359188516.123456, '2013-01-26T08:21:56.123456+00:00'];
yield 'positive integer-ish float' => [1359188516.0, '2013-01-26T08:21:56.000000+00:00'];
yield 'zero as integer' => [0, '1970-01-01T00:00:00.000000+00:00'];
yield 'zero as float' => [0.0, '1970-01-01T00:00:00.000000+00:00'];
yield 'negative integer' => [-100, '1969-12-31T23:58:20.000000+00:00'];
yield 'negative float' => [-100.123456, '1969-12-31T23:58:19.876544+00:00'];
yield 'negative integer-ish float' => [-100.0, '1969-12-31T23:58:20.000000+00:00'];
}

/**
* @dataProvider provideOutOfRangeFloatTimestamps
*/
public function testCreateFromTimestampWithFloatOutOfRange(float $timestamp)
{
$this->expectException(\DateRangeError::class);
$this->expectExceptionMessage('DateTimeImmutable::createFromTimestamp(): Argument #1 ($timestamp) must be a finite number between');
DatePoint::createFromTimestamp($timestamp);
}

public static function provideOutOfRangeFloatTimestamps(): iterable
{
yield 'too large (positive)' => [1e20];
yield 'too large (negative)' => [-1e20];
yield 'NaN' => [\NAN];
yield 'infinity' => [\INF];
}

public function testModify()
{
$date = new DatePoint('2010-01-28 15:00:00');
Expand Down

0 comments on commit 9e48e0d

Please sign in to comment.