CloudCastle Clock

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

ClockAwareTrait — setter clock injection

Purpose

A trait for services: setClock() + protected now(); falls back to the global clock when unset. Parity with symfony ClockAwareTrait, but with no container required.

What for and how to use

Lightweight managed time for existing classes: mix in the trait, in tests call setClock(new MockClock(...)).

Example

final class ReportService
{
    use ClockAwareTrait;

    public function build(): Report
    {
        return new Report(generatedAt: $this->now());
    }
}

// In a test:
$service->setClock(FrozenClock::from('2026-01-01', 'UTC'));

Anti-patterns

For new services constructor injection of ClockInterface is clearer than a setter.

Lifecycle

flowchart LR
    A[Service + ClockAwareTrait] -->|now()| B{clock set?}
    B -->|yes| C[Injected clock]
    B -->|no| D[ClockHolder global]

Feature comparison with competitors

Aspect🏆 CloudCastlesymfonycarbonlcobuccibesteergebnis
Setter clock injection✅✅❌❌❌❌
Fallback to the global clock✅✅❌❌❌❌
No container required✅❌❌❌❌❌
Protected now() for subclasses✅✅❌❌❌❌
Total🏆 430000

← Back to the feature list


🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano