Skip to content

Utilities

The clock package includes several utilities to simplify common operations.

The clock() function provides quick access to clock instances:

use function Cline\Clock\clock;
use Cline\Clock\Clocks\FrozenClock;
use DateTimeImmutable;
use DateTimeZone;
// Default CarbonImmutableClock
$clock = clock();
$now = $clock->now();
// With timezone
$clock = clock(timezone: new DateTimeZone('America/New_York'));
// Pass existing clock (returned as-is)
$frozen = new FrozenClock(new DateTimeImmutable('2025-01-15'));
$same = clock($frozen); // Returns $frozen
// Create specific clock type
$clock = clock(FrozenClock::class, frozenTime: new DateTimeImmutable('2025-01-15'));

Global registry for managing named clock instances:

use Cline\Clock\Support\ClockRegistry;
use Cline\Clock\Clocks\CarbonImmutableClock;
use Cline\Clock\Clocks\UtcClock;
use Cline\Clock\Clocks\FrozenClock;
// Register clocks
ClockRegistry::set('local', new CarbonImmutableClock());
ClockRegistry::set('utc', new UtcClock());
// Set default
ClockRegistry::setDefault('local');
// Retrieve
$local = ClockRegistry::get('local');
$default = ClockRegistry::getDefault();
// Check existence
ClockRegistry::has('utc'); // true
ClockRegistry::hasDefault(); // true
// List all registered
ClockRegistry::registered(); // ['local', 'utc']
// Remove
ClockRegistry::remove('utc');
// Clear all (useful in tests)
ClockRegistry::clear();
// Throws RuntimeException
ClockRegistry::get('nonexistent');
// Throws RuntimeException
ClockRegistry::setDefault('nonexistent');
// Throws RuntimeException
ClockRegistry::getDefault(); // When no default set
use Cline\Clock\Support\ClockRegistry;
use Cline\Clock\Clocks\CarbonImmutableClock;
use Cline\Clock\Clocks\UtcClock;
use DateTimeZone;
// Bootstrap in service provider
ClockRegistry::set('app', new CarbonImmutableClock());
ClockRegistry::set('utc', new UtcClock());
ClockRegistry::set('tokyo', new CarbonImmutableClock(new DateTimeZone('Asia/Tokyo')));
ClockRegistry::setDefault('app');
// Use throughout application
class OrderService
{
public function createOrder(array $data): Order
{
return new Order(
data: $data,
createdAt: ClockRegistry::getDefault()->now(),
createdAtUtc: ClockRegistry::get('utc')->now(),
);
}
}

The ClockComparison trait adds comparison methods to clock implementations:

use Cline\Clock\Contracts\ClockInterface;
use Cline\Clock\Support\ClockComparison;
use DateTimeImmutable;
final class MyCustomClock implements ClockInterface
{
use ClockComparison;
public function now(): DateTimeImmutable
{
return new DateTimeImmutable();
}
}
$clock = new MyCustomClock();
$reference = new DateTimeImmutable('2025-01-15 12:00:00');
// Comparisons
$clock->isAfter($reference); // true if now > reference
$clock->isBefore($reference); // true if now < reference
$clock->isSameAs($reference); // true if same timestamp
$clock->isBetween($start, $end); // true if within range (inclusive)
// Differences
$clock->diffInSeconds($reference);
$clock->diffInMinutes($reference);
$clock->diffInHours($reference);
$clock->diffInDays($reference);
MethodReturnsDescription
isAfter($time)boolClock time is after given time
isBefore($time)boolClock time is before given time
isSameAs($time)boolSame Unix timestamp
isBetween($start, $end)boolWithin range (inclusive)
diffInSeconds($time)intAbsolute difference in seconds
diffInMinutes($time)intAbsolute difference in minutes
diffInHours($time)intAbsolute difference in hours
diffInDays($time)intAbsolute difference in days
use Cline\Clock\Clocks\FrozenClock;
use Cline\Clock\Support\ClockComparison;
use DateTimeImmutable;
// Create a clock that uses the comparison trait
final class ComparableFrozenClock extends FrozenClock
{
use ClockComparison;
}
$clock = new ComparableFrozenClock(new DateTimeImmutable('2025-01-15 12:00:00'));
$past = new DateTimeImmutable('2025-01-10 12:00:00');
$future = new DateTimeImmutable('2025-01-20 12:00:00');
// Time comparisons
$clock->isAfter($past); // true
$clock->isBefore($future); // true
$clock->isBetween($past, $future); // true
// Differences
$clock->diffInDays($past); // 5
$clock->diffInDays($future); // 5 (absolute)

Production clocks implement FreezableInterface for creating frozen snapshots:

use Cline\Clock\Clocks\CarbonImmutableClock;
$clock = new CarbonImmutableClock();
// Create frozen snapshot
$frozen = $clock->freeze();
// Original continues
sleep(1);
$clock->now(); // Current time
$frozen->now(); // Time when freeze() was called
use Cline\Clock\Contracts\ClockInterface;
use Cline\Clock\Contracts\FreezableInterface;
use Cline\Clock\Clocks\FrozenClock;
use DateTimeImmutable;
final readonly class MyCustomClock implements ClockInterface, FreezableInterface
{
public function now(): DateTimeImmutable
{
return new DateTimeImmutable();
}
public function freeze(): FrozenClock
{
return new FrozenClock($this->now());
}
}