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

lcobucci/clock

Clock abstraction for PHP to decouple your code from DateTimeImmutable instantiation. Depend on the Clock interface and use SystemClock for real time (with timezone support) or FrozenClock for deterministic, test-friendly time in unit tests.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require lcobucci/clock
    
  2. Basic Usage: Inject Clock interface into your services. Use SystemClock in production and FrozenClock in tests:

    use Lcobucci\Clock\Clock;
    use Lcobucci\Clock\SystemClock;
    
    class MyService {
        public function __construct(private Clock $clock) {}
    
        public function getCurrentTime() {
            return $this->clock->now();
        }
    }
    
  3. First Use Case: Replace new DateTimeImmutable() calls with $clock->now() in business logic. Example:

    $expired = $clock->now() > $item->expiryDate;
    

Where to Look First

  • Interface: Lcobucci\Clock\Clock (PSR-20 compliant)
  • Implementations:
    • SystemClock (production)
    • FrozenClock (testing)
  • Named Constructors: SystemClock::fromUTC(), FrozenClock::fromUTC()

Implementation Patterns

Dependency Injection

  1. Service Container Setup (Laravel):

    // app/Providers/AppServiceProvider.php
    public function register() {
        $this->app->bind(Clock::class, function() {
            return new SystemClock(new DateTimeZone('UTC'));
        });
    }
    
  2. Testing Setup:

    $this->app->instance(Clock::class, new FrozenClock(new DateTimeImmutable('2023-01-01')));
    

Common Workflows

  1. Time-Based Logic:

    class Order {
        public function isExpired(Clock $clock): bool {
            return $clock->now() > $this->expiryDate;
        }
    }
    
  2. Time Adjustments:

    // For testing time travel
    $clock = new FrozenClock($baseTime->modify('+1 day'));
    
  3. Timezone Handling:

    // Explicit timezone binding
    $this->app->bind(Clock::class, fn() => new SystemClock(new DateTimeZone('America/New_York')));
    

Integration Tips

  1. Laravel Carbon Compatibility:

    $carbonTime = Carbon::instance($clock->now());
    
  2. Database Operations:

    // Use clock time for timestamps
    $record->created_at = $clock->now()->format('Y-m-d H:i:s');
    
  3. Event Scheduling:

    // Schedule events based on clock time
    $event->scheduleAt($clock->now()->modify('+1 hour'));
    

Gotchas and Tips

Pitfalls

  1. Timezone Ambiguity:

    • Always explicitly set timezones in SystemClock to avoid relying on system defaults.
    • Example: SystemClock::fromUTC() vs SystemClock::fromSystemTimezone().
  2. Immutable Objects:

    • SystemClock is immutable. Avoid modifying instances after creation.
  3. DateTimeImmutable:

    • The package returns DateTimeImmutable objects. Ensure your code handles these properly (e.g., no modify() calls that return DateTime).

Debugging

  1. Clock Time Mismatch:

    • Verify timezone consistency between SystemClock and application logic.
    • Use FrozenClock to debug time-sensitive operations.
  2. Performance:

    • SystemClock is lightweight. Avoid creating multiple instances unnecessarily.

Extension Points

  1. Custom Clock Implementations:

    class CustomClock implements Clock {
        public function now(): DateTimeImmutable {
            return new DateTimeImmutable('now', new DateTimeZone('Custom/Timezone'));
        }
    }
    
  2. Time Adjustment:

    // For testing relative time changes
    $clock = new FrozenClock($baseTime);
    $adjustedClock = new class($clock) implements Clock {
        public function now(): DateTimeImmutable {
            return $this->clock->now()->modify('+2 hours');
        }
    };
    

Configuration Quirks

  1. Laravel Configuration:

    • Bind the clock in AppServiceProvider to ensure consistency across the application.
    • Example:
      $this->app->singleton(Clock::class, fn() => new SystemClock(new DateTimeZone(config('app.timezone'))));
      
  2. Testing:

    • Use FrozenClock for unit tests to isolate time-dependent logic.
    • Example:
      $this->beforeApplicationDestroyed(function () {
          $this->app->instance(Clock::class, new SystemClock(new DateTimeZone('UTC')));
      });
      

Pro Tips

  1. Time Travel Testing:

    // Test future/past scenarios
    $futureClock = new FrozenClock(new DateTimeImmutable('+1 year'));
    $this->app->instance(Clock::class, $futureClock);
    
  2. Performance Testing:

    • Benchmark SystemClock vs FrozenClock in high-frequency operations.
  3. Legacy Code:

    • Use a decorator pattern to wrap existing DateTime logic:
      class ClockDecorator implements Clock {
          public function __construct(private Clock $clock) {}
      
          public function now(): DateTimeImmutable {
              return $this->clock->now();
          }
      }
      
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
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