🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano
ClockHolder — global clock with scoped substitution
Purpose
A global application clock slot: set()/get()/reset() and within($clock, $fn) — temporary substitution with guaranteed restoration even on exceptions.
What for and how to use
A bridge for DI-free code and for DatePoint; in tests within() isolates the substitution from neighbouring tests.
Example
$result = ClockHolder::within(
MockClock::from('2026-01-01 00:00:00', 'UTC'),
fn () => $service->generateReport(), // inside, “now” is 2026-01-01
);
// the global clock is restored automatically
Anti-patterns
Global state is a conscious trade-off: in new services inject ClockInterface directly.
Lifecycle
sequenceDiagram
participant T as Caller
participant H as ClockHolder
T->>H: within(mock, fn)
H->>H: save previous, set mock
H->>T: fn() result
H->>H: restore previous (finally)
Feature comparison with competitors
| Aspect | 🏆 CloudCastle | symfony | carbon | lcobucci | beste | ergebnis |
|---|---|---|---|---|---|---|
| Scoped substitution with auto-restore | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Restoration on exception | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| System clock default when unset | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Explicit isSet()/reset() | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Total | 🏆 4 | 1 | 3 | 0 | 0 | 0 |
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano