|  | 
|  | 1 | +<?php | 
|  | 2 | + | 
|  | 3 | +declare(strict_types=1); | 
|  | 4 | + | 
|  | 5 | +/** | 
|  | 6 | + * This file is part of the Nexus framework. | 
|  | 7 | + * | 
|  | 8 | + * (c) John Paul E. Balandan, CPA <[email protected]> | 
|  | 9 | + * | 
|  | 10 | + * For the full copyright and license information, please view | 
|  | 11 | + * the LICENSE file that was distributed with this source code. | 
|  | 12 | + */ | 
|  | 13 | + | 
|  | 14 | +namespace Nexus\Clock; | 
|  | 15 | + | 
|  | 16 | +/** | 
|  | 17 | + * A reference to the internal clock. | 
|  | 18 | + * | 
|  | 19 | + * This is primarily useful for mocking the clock in tests. | 
|  | 20 | + * Classes should not use this class directly, but instead | 
|  | 21 | + * use the `Clock` interface or the two traits `ClockAware` | 
|  | 22 | + * and `ImmutableClockAware`. | 
|  | 23 | + * | 
|  | 24 | + * @internal | 
|  | 25 | + */ | 
|  | 26 | +final class InternalClock implements Clock | 
|  | 27 | +{ | 
|  | 28 | +    private static ?Clock $internalClock; | 
|  | 29 | + | 
|  | 30 | +    public function __construct( | 
|  | 31 | +        private readonly ?Clock $innerClock = null, | 
|  | 32 | +        private ?\DateTimeZone $timezone = null, | 
|  | 33 | +    ) {} | 
|  | 34 | + | 
|  | 35 | +    /** | 
|  | 36 | +     * Returns the current internal clock. | 
|  | 37 | +     * | 
|  | 38 | +     * If no internal clock has been set, a new instance of SystemClock | 
|  | 39 | +     * will be created with the UTC timezone. | 
|  | 40 | +     */ | 
|  | 41 | +    public static function getCurrent(): Clock | 
|  | 42 | +    { | 
|  | 43 | +        self::$internalClock ??= new SystemClock('UTC'); | 
|  | 44 | + | 
|  | 45 | +        return self::$internalClock; | 
|  | 46 | +    } | 
|  | 47 | + | 
|  | 48 | +    /** | 
|  | 49 | +     * Sets the internal clock. | 
|  | 50 | +     */ | 
|  | 51 | +    public static function set(?Clock $clock): void | 
|  | 52 | +    { | 
|  | 53 | +        self::$internalClock = $clock; | 
|  | 54 | +    } | 
|  | 55 | + | 
|  | 56 | +    public function now(): \DateTimeImmutable | 
|  | 57 | +    { | 
|  | 58 | +        $now = ($this->innerClock ?? self::getCurrent())->now(); | 
|  | 59 | + | 
|  | 60 | +        if (null !== $this->timezone) { | 
|  | 61 | +            $now = $now->setTimezone($this->timezone); | 
|  | 62 | +        } | 
|  | 63 | + | 
|  | 64 | +        return $now; | 
|  | 65 | +    } | 
|  | 66 | + | 
|  | 67 | +    public function sleep(float|int $seconds): void | 
|  | 68 | +    { | 
|  | 69 | +        ($this->innerClock ?? self::getCurrent())->sleep($seconds); | 
|  | 70 | +    } | 
|  | 71 | +} | 
0 commit comments