Skip to content

Commit

Permalink
FrozenClock: accepts DateTimeInterface as the initial time
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar committed Nov 27, 2023
1 parent 32f1b0d commit 588beb6
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- `PsrToOrisaiClockAdapter` - makes any PSR clock compatible with `Orisai\Clock\Clock`
- `SymfonyToOrisaiClockAdapter` - makes any symfony/clock compatible with `Orisai\Clock\Clock`
- `ClockAdapterFactory` - chooses best supported adapter for `Orisai\Clock\Clock` compatibility
- `FrozenClock` - accepts `DateTimeInterface` as the initial time

### Changed

Expand Down
11 changes: 11 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ use DateTimeZone;
$clock = new FrozenClock(0, new DateTimeZone('UTC'));
```

You can also create clock from datetime

```php
use DateTime;
use DateTimeImmutable;

$clock = new FrozenClock(new DateTimeImmutable());
// or
$clock = new FrozenClock(new DateTime());
```

[Sleeping](#sleep) does not put thread to sleep but just moves timestamp of clock's internal `DateTimeImmutable`.

### Measurement clock
Expand Down
21 changes: 16 additions & 5 deletions src/FrozenClock.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Orisai\Clock;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use function date_default_timezone_get;
use function floor;
Expand All @@ -16,13 +18,22 @@ final class FrozenClock implements Clock

private DateTimeImmutable $dt;

public function __construct(float $timestamp, ?DateTimeZone $timeZone = null)
/**
* @param float|DateTimeInterface $timestamp
*/
public function __construct($timestamp, ?DateTimeZone $timeZone = null)
{
[$seconds, $microseconds] = $this->getParts($timestamp);
if ($timestamp instanceof DateTime) {
$dt = DateTimeImmutable::createFromMutable($timestamp);
} elseif ($timestamp instanceof DateTimeImmutable) {
$dt = $timestamp;
} else {
[$seconds, $microseconds] = $this->getParts($timestamp);
$dt = DateTimeImmutable::createFromFormat('U', (string) $seconds)
->modify("+$microseconds microsecond");
}

$this->dt = DateTimeImmutable::createFromFormat('U', (string) $seconds)
->setTimezone($timeZone ?? new DateTimeZone(date_default_timezone_get()))
->modify("+$microseconds microsecond");
$this->dt = $dt->setTimezone($timeZone ?? new DateTimeZone(date_default_timezone_get()));
}

public function now(): DateTimeImmutable
Expand Down
33 changes: 33 additions & 0 deletions tests/Unit/FrozenClockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

namespace Tests\Orisai\Clock\Unit;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use Generator;
use Orisai\Clock\FrozenClock;
use PHPUnit\Framework\TestCase;
use function date_default_timezone_get;
Expand Down Expand Up @@ -40,6 +44,35 @@ public function testFrozenTime(): void
self::assertSame('1.000000', $now);
}

/**
* @param int|DateTimeInterface $datetime
*
* @dataProvider provideTimestampVariants
*/
public function testTimestampVariants($datetime, int $timestamp): void
{
$clock = new FrozenClock($datetime);
self::assertSame($timestamp, $clock->now()->getTimestamp());
}

public function provideTimestampVariants(): Generator
{
yield [
1,
1,
];

yield [
DateTimeImmutable::createFromFormat('U', '1'),
1,
];

yield [
DateTime::createFromFormat('U', '1'),
1,
];
}

public function testTimeDoesNotChange(): void
{
$clock = new FrozenClock(1);
Expand Down
14 changes: 7 additions & 7 deletions tools/phpstan.baseline.neon
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
parameters:
ignoreErrors:
-
message: "#^Cannot call method setTimezone\\(\\) on DateTimeImmutable\\|false\\.$#"
message: "#^Cannot call method modify\\(\\) on DateTimeImmutable\\|false\\.$#"
count: 1
path: ../src/FrozenClock.php

-
message: "#^Property Orisai\\\\Clock\\\\FrozenClock\\:\\:\\$dt \\(DateTimeImmutable\\) does not accept \\(DateTimeImmutable\\|false\\)\\.$#"
count: 5
count: 4
path: ../src/FrozenClock.php

-
Expand All @@ -20,15 +20,15 @@ parameters:
count: 1
path: ../src/MeasurementClock.php

-
message: "#^Parameter \\#1 \\$now of class Symfony\\\\Component\\\\Clock\\\\MockClock constructor expects DateTimeImmutable\\|string, DateTimeImmutable\\|false given\\.$#"
count: 2
path: ../tests/Unit/Adapter/SymfonyToOrisaiClockAdapterTest.php

-
message: """
#^Call to deprecated method move\\(\\) of class Orisai\\\\Clock\\\\FrozenClock\\:
Method move\\(\\) will be removed in orisai/clock v2\\.0\\. Use method sleep\\(\\) instead\\.$#
"""
count: 9
path: ../tests/Unit/FrozenClockTest.php

-
message: "#^Parameter \\#1 \\$now of class Symfony\\\\Component\\\\Clock\\\\MockClock constructor expects DateTimeImmutable\\|string, DateTimeImmutable\\|false given\\.$#"
count: 2
path: ../tests/Unit/Adapter/SymfonyToOrisaiClockAdapterTest.php

0 comments on commit 588beb6

Please sign in to comment.