value)->toBeInstanceOf(\DateTimeImmutable::class) ->and($dateTime->value->getTimezone()->getName())->toBe('UTC') ->and($dateTime->value->format('H:i:s'))->toBe('12:00:00'); }); it('parses a valid date string', function (): void { // WHEN $dateTime = new DateTime('2026-01-15'); // THEN expect($dateTime->value->format('Y-m-d'))->toBe('2026-01-15'); }); it('rejects an invalid date string', function (): void { // WHEN $action = fn (): DateTime => new DateTime('not-a-date'); // THEN expect($action)->toThrow(InvalidDateFormatException::class); }); it('creates the current instant via now', function (): void { // GIVEN \Carbon\CarbonImmutable::setTestNow('2026-06-15T12:00:00Z'); // WHEN $dateTime = DateTime::now(); // THEN expect($dateTime)->toBeInstanceOf(DateTime::class) ->and($dateTime->value->getTimezone()->getName())->toBe('UTC') ->and($dateTime->value->format(\DateTimeInterface::ATOM))->toBe('2026-06-15T12:00:00+00:00'); // TEARDOWN \Carbon\CarbonImmutable::setTestNow(); }); it('implements equals correctly', function (): void { // GIVEN $a = new DateTime('2026-01-15T10:00:00Z'); $b = new DateTime('2026-01-15T10:00:00Z'); $c = new DateTime('2026-01-16T10:00:00Z'); // THEN expect($a->equals($b))->toBeTrue() ->and($a->equals($c))->toBeFalse() ->and($a->equals(null))->toBeFalse(); }); it('converts to a RFC3339 string', function (): void { // GIVEN $dateTime = new DateTime('2026-01-15T10:00:00Z'); // THEN expect((string) $dateTime)->toBe(DatesHelper::toRfc3339($dateTime->value)); }); it('serializes to json as a RFC3339 string', function (): void { // GIVEN $dateTime = new DateTime('2026-01-15T10:00:00Z'); // THEN expect($dateTime->jsonSerialize())->toBe((string) $dateTime); }); });