now(); $utcNow = $utcClock->now(); // THEN expect($parisClock)->toBeInstanceOf(ClockInterface::class) ->and($parisClock)->toBeInstanceOf(Clock::class) ->and($parisNow->getTimezone()->getName())->toBe('Europe/Paris') ->and($parisClock->timezone()->getName())->toBe('Europe/Paris') ->and($utcNow->getTimezone()->getName())->toBe('UTC'); }); it('parses date strings and normalizes to UTC with SystemUtcClock', function (): void { // GIVEN $clock = new SystemUtcClock(); // WHEN $utcTime = $clock->parse('2026-08-21T15:00:00+02:00'); $startOfDay = $clock->startOfDay('2026-08-21'); $endOfDay = $clock->endOfDay('2026-08-21'); $isoString = $clock->toIso8601($utcTime); // THEN expect($utcTime->getTimezone()->getName())->toBe('UTC') ->and($utcTime->format('Y-m-d H:i:s'))->toBe('2026-08-21 13:00:00') ->and($startOfDay->format('Y-m-d H:i:s'))->toBe('2026-08-21 00:00:00') ->and($endOfDay->format('Y-m-d H:i:s.u'))->toBe('2026-08-21 23:59:59.999999') ->and($isoString)->toBe('2026-08-21T13:00:00+00:00'); }); it('allows freezing and manipulating time with FrozenClock', function (): void { // GIVEN $fixedTime = new \DateTimeImmutable('2026-08-21 10:00:00', new \DateTimeZone('UTC')); $frozenClock = new FrozenClock($fixedTime); // THEN expect($frozenClock->now()->format('Y-m-d H:i:s'))->toBe('2026-08-21 10:00:00'); // WHEN $frozenClock->setTo('2026-12-31 23:59:59'); // THEN expect($frozenClock->now()->format('Y-m-d H:i:s'))->toBe('2026-12-31 23:59:59') ->and($frozenClock->now()->getTimezone()->getName())->toBe('UTC'); }); it('provides centralized static access through Utc facade', function (): void { // GIVEN $frozen = Utc::freeze(new \DateTimeImmutable('2026-08-21 14:00:00', new \DateTimeZone('UTC'))); // THEN expect(Utc::now()->format('Y-m-d H:i:s'))->toBe('2026-08-21 14:00:00') ->and(Utc::parse('2026-08-21 12:00:00')->format('Y-m-d H:i:s'))->toBe('2026-08-21 12:00:00') ->and(Utc::startOfDay('2026-08-21')->format('Y-m-d H:i:s'))->toBe('2026-08-21 00:00:00') ->and(Utc::endOfDay('2026-08-21')->format('Y-m-d H:i:s'))->toBe('2026-08-21 23:59:59') ->and(Utc::toRfc3339('2026-08-21 14:00:00'))->toBe('2026-08-21T14:00:00+00:00') ->and(Utc::toNullableRfc3339(null))->toBeNull() ->and(Utc::toNullableRfc3339('2026-08-21 14:00:00'))->toBe('2026-08-21T14:00:00+00:00'); // WHEN Utc::restore(); // THEN expect(Utc::getClock())->toBeInstanceOf(SystemUtcClock::class); }); });