Lines 100.00% 6 / 6
Functions and Methods 100.00% 6 / 6
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
SystemClock 100.00% 6 / 6 100.00% 6 / 6 6 100.00% 1 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 inUtc 100.00% 1 / 1 100.00% 1 / 1 1
 getNow 100.00% 1 / 1 100.00% 1 / 1 1
 getMonotonicTime 100.00% 1 / 1 100.00% 1 / 1 1
 getTimeZone 100.00% 1 / 1 100.00% 1 / 1 1
 isWithin 100.00% 1 / 1 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Runtime\Time;
6
7use DateTimeImmutable;
8use DateTimeZone;
9use Stewart\Contracts\Schedule\TimeOfDay;
10use Stewart\Contracts\Time\Clock;
11use Stewart\Contracts\Time\Instant;
12use Stewart\Contracts\Time\MonotonicTime;
13use Stewart\Support\Schedule\TimeWindow;
14
15final readonly class SystemClock implements Clock
16{
17    public function __construct(private DateTimeZone $timeZone) {}
18
19    public static function inUtc(): self
20    {
21        return new self(new DateTimeZone('UTC'));
22    }
23
24    public function getNow(): Instant
25    {
26        return Instant::fromDateTime(new DateTimeImmutable('now', $this->timeZone));
27    }
28
29    public function getMonotonicTime(): MonotonicTime
30    {
31        // Revolt timers use hrtime(), so this matches the clock they fire on.
32        return MonotonicTime::fromMicroseconds(intdiv((int) hrtime(true), 1_000));
33    }
34
35    public function getTimeZone(): DateTimeZone
36    {
37        return $this->timeZone;
38    }
39
40    public function isWithin(TimeOfDay|string $start, TimeOfDay|string $end): bool
41    {
42        return TimeWindow::between($start, $end)->includes($this->getNow()->toDateTime($this->getTimeZone()));
43    }
44}