Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Clock Laravel Package

symfony/clock

Symfony Clock decouples your code from the system clock. Inject ClockInterface to get DateTimeImmutable via now(), control timezones, and pause execution with sleep(). Ideal for testable, time-sensitive services without relying on global time.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Decoupling Time Logic: Aligns perfectly with Laravel’s dependency injection (DI) and service container patterns. The ClockInterface can be injected into services, controllers, or jobs, replacing direct calls to now(), Carbon::now(), or time().
  • Testability: Solves a critical pain point in Laravel applications where time-dependent logic (e.g., feature flags, rate limiting, subscriptions) is hard to test due to system clock variability. Enables deterministic testing by replacing NativeClock with MockClock in tests.
  • Time Zone Isolation: Addresses global deployment challenges by allowing explicit timezone configuration (e.g., forcing UTC for internal services). Prevents bugs where local system time differs between dev/staging/production.
  • Laravel Compatibility: Works seamlessly with:
    • Laravel’s Service Container: Register ClockInterface as a singleton or bind it to specific implementations.
    • Laravel Jobs/Queues: Replace sleep() or usleep() in background jobs with $clock->sleep() for predictable delays.
    • Laravel Testing: Integrates with ClockSensitiveTrait and can replace Carbon::setTestNow() or travel() in legacy tests.
  • Event Sourcing & Observability: Supports time-warping for replaying events or debugging race conditions, which is valuable for audit logs or event-driven architectures.

Integration Feasibility

  • Low Friction: Requires minimal changes to existing code. The ClockInterface can be incrementally adopted:
    1. Start by injecting it into test-sensitive classes (e.g., subscription logic, feature flags).
    2. Gradually replace now() calls with $clock->now() in production.
    3. Replace sleep()/usleep() with $clock->sleep() in jobs.
  • Backward Compatibility: Does not break existing Carbon or DateTime usage. Can coexist with legacy code.
  • Laravel-Specific Integrations:
    • Artisan Commands: Inject ClockInterface to control time in CLI tools (e.g., php artisan migrate --force with a fixed timestamp).
    • Horizon/Queues: Use $clock->sleep() for reliable job delays (e.g., retries, exponential backoff).
    • Broadcasting: Simulate real-time delays in WebSocket events for testing.

Technical Risk

Risk Area Mitigation Strategy
Breaking Changes Minimal risk: ClockInterface is stable; only replaces direct time calls.
Performance Overhead Negligible: NativeClock uses DateTimeImmutable, which is optimized in PHP.
Testing Complexity Reduces complexity: Replaces flaky time-based tests with deterministic mocks.
Time Zone Bugs Eliminates risk by enforcing explicit timezone handling (e.g., withTimeZone('UTC')).
Legacy Code Incremental adoption: Start with new features; refactor old code as needed.
PHP Version Requires PHP 8.1+ (for Symfony 7+) or PHP 8.4+ (for Symfony 8+). Check compatibility.
MockClock Behavior Aligned with NativeClock for negative sleep() values (fixed in v7.3.8+).

Key Questions

  1. Adoption Scope:
    • Should we adopt this globally (all time-dependent logic) or incrementally (start with tests/jobs)?
    • Which time-sensitive features (subscriptions, rate limiting, feature flags) will benefit most?
  2. Clock Implementation:
    • Will we use NativeClock in production, or build a custom clock (e.g., Redis-backed for distributed systems)?
    • Should we enforce a default timezone (e.g., UTC) for all services?
  3. Testing Strategy:
    • How will we migrate from Carbon::setTestNow()/travel() to MockClock?
    • Should we deprecate legacy time functions (e.g., time(), date()) in favor of $clock->now()?
  4. Performance:
    • Will $clock->sleep() replace usleep() in high-frequency jobs (e.g., WebSocket heartbeats)?
    • Are there edge cases (e.g., microsecond precision) where NativeClock may not suffice?
  5. Monitoring:
    • How will we audit time-based decisions (e.g., "Why was this user locked at this timestamp")?
    • Should we log ClockInterface usage for observability?
  6. Long-Term Roadmap:
    • Could this enable time-warping features (e.g., "rewind time to debug a failed payment")?
    • Will it support event sourcing or CQRS patterns in future architecture?

Integration Approach

Stack Fit

  • Laravel Ecosystem:
    • Service Container: Bind ClockInterface to NativeClock in AppServiceProvider:
      $this->app->singleton(ClockInterface::class, fn() => new NativeClock());
      
    • Jobs/Queues: Replace sleep() calls in jobs with $clock->sleep() for deterministic delays.
    • Testing: Use MockClock in PHPUnit tests to control time progression.
    • Artisan: Inject ClockInterface into commands for reproducible CLI operations.
  • Symfony Integration:
    • Works alongside Symfony’s HTTP Client, Messenger, or Workflow components where time is critical.
    • Compatible with Laravel’s Symfony bridge (e.g., symfony/mailer, symfony/http-client).
  • Third-Party Packages:
    • Replaces time functions in packages like:
      • Spatie’s Rate Limiting (spatie/laravel-rate-limiter).
      • Cashier/Stripe Subscriptions (laravel/cashier).
      • Laravel Horizon (for job delays).
    • Can be used with Carbon (via DateTimeImmutable compatibility).

Migration Path

Phase Action Items Laravel-Specific Steps
Assessment Audit time-dependent logic (e.g., now(), time(), Carbon::now(), sleep()). Run grep for `now
Setup Install package and register ClockInterface in Laravel’s service container. Add to composer.json; bind in AppServiceProvider.
Testing Replace Carbon::setTestNow()/travel() with MockClock in unit tests. Use ClockSensitiveTrait or manually inject MockClock in tests.
Jobs/Queues Replace sleep()/usleep() in jobs with $clock->sleep(). Update App\Jobs\* classes to inject ClockInterface.
Controllers Inject ClockInterface into controllers for time-sensitive logic (e.g., feature flags). Use constructor injection in App\Http\Controllers\*.
Artisan Inject ClockInterface into custom Artisan commands. Add to command constructors (e.g., php artisan my:time-sensitive-command).
Legacy Refactor Replace direct now() calls with $clock->now() in critical paths. Start with high-risk areas (e.g., subscriptions, payments).
Monitoring Add logging for ClockInterface usage (e.g., "Time decision: [timestamp]"). Use Laravel’s logging or Symfony’s Monolog integration.

Compatibility

  • PHP Versions:
    • Symfony 7.x: PHP 8.1+.
    • Symfony 8.x: PHP 8.4+.
    • Recommendation: Target PHP 8.2+ for broad Laravel compatibility.
  • Laravel Versions:
    • Works with Laravel 9+ (Symfony 6+) and Laravel 10+ (Symfony 7/8).
    • Laravel 8: Requires Symfony 5.4+ (may need manual DI setup).
  • Dependencies:
    • No conflicts with carbon/carbon (both use DateTimeImmutable under the hood).
    • Compatible with spatie/laravel-activitylog, spatie/laravel-permission, etc.
  • Database:
    • Does not interact with databases directly, but can be used to generate timestamps for Eloquent models.

Sequencing

  1. Phase 1: Testing (2-4 weeks)
    • Replace time manipulation in unit tests (high ROI, low risk).
    • Example: Convert
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi