symfony/clock
Symfony Clock decouples your app from the system clock via a ClockInterface. Swap real and test clocks, get DateTimeImmutable “now()” values, control time zones, and pause execution with sleep()—ideal for time-sensitive code and reliable testing.
time(), Carbon::now(), or DateTime::createFromFormat(). Aligns with Laravel’s service container and testing best practices (e.g., mocking dependencies).NativeClock).ClockSensitiveTrait (v7.1.0+), reducing boilerplate.travel()) by providing a unified clock abstraction.sleep() with $clock->sleep() for deterministic delays in background workers.UTC for APIs, America/New_York for user-facing logic).DateTimeImmutable/Carbon usage remains valid; ClockInterface adds a layer of abstraction.ClockInterface replaces static calls (e.g., now() → $clock->now()).Carbon::setTestNow() or Time::fake() with a standardized mock clock (MockClock).sleep()).NativeClock uses DateTimeImmutable (microsecond precision) with minimal abstraction cost.$clock->sleep() avoids usleep() inaccuracies in PHP’s event loop (e.g., queues, cron).| Risk Area | Mitigation Strategy | Severity |
|---|---|---|
| Breaking Changes | Use feature flags to toggle clock usage; migrate services incrementally. | Low |
| Test Coverage Gaps | Adopt clock-aware testing (e.g., MockClock for edge cases like negative sleep()). |
Medium |
| Timezone Complexity | Enforce UTC for APIs, regional timezones for UI; validate with withTimeZone(). |
Medium |
| Legacy Code | Use decorator pattern to wrap existing time functions (e.g., ClockDecorator). |
Low |
| PHP Version Constraints | Require PHP 8.1+ (Laravel 10+) for DateTimeImmutable improvements. |
Low |
| Clock Drift in Distributed Systems | Use monotonic clocks (e.g., ClockInterface with CLOCK_MONOTONIC backend) for critical paths. |
High (if applicable) |
ClockInterface for all new time-dependent services, or opt-in for critical paths (e.g., payments, subscriptions)?NativeClock in production, or build a custom clock (e.g., Redis-backed, NTP-synchronized)?MockClock by default, with opt-out for system time).time()/Carbon::now() calls? (e.g., 6–12 months).ClockInterface overhead matters?MockClock in test environment") for debugging?ClockInterface as a singleton/binding (e.g., NativeClock in production, MockClock in tests).Carbon::setTestNow() with MockClock for deterministic time control.$clock->sleep() in delayed jobs or cron tasks for predictable pauses.ClockInterface into controllers/services to standardize time handling (e.g., withTimeZone('UTC')).ClockSensitiveTrait to reduce boilerplate in services.MockClock for time-freezing in unit tests.ClockInterface (e.g., $clock->now()->toCarbon()).$clock->sleep(5) before retrying).ClockInterface to replay events in sequence (e.g., EventStore with controlled time).| Phase | Action Items | Dependencies | Risk |
|---|---|---|---|
| Assessment | Audit time-dependent code (e.g., time(), Carbon::now(), sleep() calls). |
Static analysis tools (e.g., PHPStan). | Low |
| Pilot | Migrate 1–2 critical services (e.g., subscriptions, payments). | Clock-aware testing framework. | Medium |
| Core Integration | Register ClockInterface in Laravel’s container; replace now() with $clock->now(). |
Laravel 10+ (PHP 8.1+). | Low |
| Testing Overhaul | Replace Carbon::setTestNow() with MockClock; add time-warping tests. |
PHPUnit 10+ attributes. | Medium |
| Legacy Wrappers | Create decorators for remaining time()/Carbon calls (e.g., ClockDecorator). |
None. | Low |
| Production Rollout | Deploy NativeClock; monitor for timezone/performance issues. |
Feature flags for gradual rollout. | High (if issues arise) |
DateTimeImmutable improvements).DateTimeImmutable.symfony/clock’s DateTimeImmutable backport).DateTime must be enabled (standard in PHP).created_at vs. $clock->now()).Carbon::setTestNow() with MockClock in CI/CD pipelines.ClockInterface.sleep()/usleep() in queues/cron with $clock->sleep().MockClock).ClockInterface into controllers to standardize timezone handling.time()/`Carbon::nowHow can I help you explore Laravel packages today?