get($model, 'created_at', '2026-08-21 14:30:00', []); // THEN expect($result)->toBeInstanceOf(\DateTimeImmutable::class) ->and($result?->getTimezone()->getName())->toBe('UTC') ->and($result?->format('Y-m-d H:i:s'))->toBe('2026-08-21 14:30:00'); }); it('casts non-UTC DateTimeInterface to UTC DateTimeImmutable upon get', function (): void { // GIVEN $cast = new UtcDateTimeCast(); $model = new class () extends Model { }; $parisDate = new \DateTimeImmutable('2026-08-21 16:30:00', new \DateTimeZone('Europe/Paris')); // WHEN $result = $cast->get($model, 'created_at', $parisDate, []); // THEN expect($result)->toBeInstanceOf(\DateTimeImmutable::class) ->and($result?->getTimezone()->getName())->toBe('UTC') ->and($result?->format('Y-m-d H:i:s'))->toBe('2026-08-21 14:30:00'); }); it('handles null and empty string upon get', function (): void { // GIVEN $cast = new UtcDateTimeCast(); $model = new class () extends Model { }; // WHEN & THEN expect($cast->get($model, 'created_at', null, []))->toBeNull() ->and($cast->get($model, 'created_at', '', []))->toBeNull() ->and($cast->get($model, 'created_at', ' ', []))->toBeNull(); }); it('sets DateTimeInterface to UTC string format for database storage', function (): void { // GIVEN $cast = new UtcDateTimeCast(); $model = new class () extends Model { }; $parisDate = new \DateTimeImmutable('2026-08-21 16:30:00', new \DateTimeZone('Europe/Paris')); // WHEN $result = $cast->set($model, 'created_at', $parisDate, []); // THEN expect($result)->toBe('2026-08-21 14:30:00'); }); it('sets string date to UTC string format for database storage', function (): void { // GIVEN $cast = new UtcDateTimeCast(); $model = new class () extends Model { }; // WHEN $result = $cast->set($model, 'created_at', '2026-08-21T16:30:00+02:00', []); // THEN expect($result)->toBe('2026-08-21 14:30:00'); }); it('handles null and empty string upon set', function (): void { // GIVEN $cast = new UtcDateTimeCast(); $model = new class () extends Model { }; // WHEN & THEN expect($cast->set($model, 'created_at', null, []))->toBeNull() ->and($cast->set($model, 'created_at', '', []))->toBeNull() ->and($cast->set($model, 'created_at', ' ', []))->toBeNull(); }); it('throws InvalidArgumentException when setting unsupported type', function (): void { // GIVEN $cast = new UtcDateTimeCast(); $model = new class () extends Model { }; // WHEN & THEN expect(fn () => $cast->set($model, 'created_at', 12345, [])) ->toThrow(\InvalidArgumentException::class, 'Cannot cast value of type int to UTC datetime'); }); });