Skip to content

Feature System clock

github-actions[bot] edited this page Jul 14, 2026 · 1 revision

⏰ Системные часы — SystemClock

← Возможности · Главная · Сравнение

Продакшн-реализация PSR-20: отдаёт реальное время операционной системы.

Принцип работы

Создаётся только именованными фабриками. Горячий путь now() максимально дёшев: при системной таймзоне объект зоны вообще не создаётся, timestamp()/microtime() не создают объектов дат. UTC-экземпляр кэшируется — utc() всегда возвращает один и тот же объект.

use CloudCastle\Clock\SystemClock;

$clock = SystemClock::system();                    // системная таймзона процесса
$utc = SystemClock::utc();                         // UTC, кэшированный экземпляр
$moscow = SystemClock::fromTimezone('Europe/Moscow');

$moment = $clock->now();          // DateTimeImmutable
$unix = $clock->timestamp();      // int, без создания объекта
$micro = $clock->microtime();     // float, секунды.микросекунды

SystemClock реализует SleepableClockInterface — умеет честно блокировать процесс:

$clock->sleep(0.25);                                   // 250 мс
$clock->sleepUntil(new DateTimeImmutable('+1 second')); // до момента

Прерывание sleep() сигналом (например, SIGALRM) не укорачивает паузу: остаток досыпается автоматически.

Плюсы

  • Ноль накладных расходов в timestamp()/microtime() — это прямые time()/microtime(true).
  • Кэшированный utc() — не плодит объекты в DI-контейнерах и фабриках.
  • sleep() устойчив к сигналам — редкое свойство даже среди «взрослых» реализаций.

Минусы

  • Это реальное время: тесты с ним недетерминированы — берите FrozenClock/MockClock.
  • sleep() блокирует процесс — в асинхронном коде (Fiber/event-loop) применяйте средства своего рантайма.

✅ Рекомендуется

  • Внедрять как Psr\Clock\ClockInterface через DI и подменять в тестах.
  • Для сравнения моментов между серверами использовать utc().

❌ Антипаттерны

  • new DateTimeImmutable() напрямую в бизнес-коде — время становится нетестируемым.
  • SystemClock в юнит-тестах с проверками конкретных моментов — флаки гарантированы.

Схема фичи

flowchart LR
    F1["system()"] -->|кэш экземпляра по зоне| SC[SystemClock]
    F2["utc()"] -->|кэш| SC
    F3["fromTimezone(tz)"] --> SC
    SC -->|"now()"| DTI[DateTimeImmutable]
    SC -->|"timestamp() → time()"| INT[int]
    SC -->|"microtime()"| FLT[float]
Loading

Жизненный цикл sleep()

flowchart TD
    A["sleep(seconds)"] --> B["Duration::splitSeconds<br/>валидация ≥ 0"]
    B --> C["time_nanosleep(s, ns)"]
    C -->|завершился| E[возврат]
    C -->|прерван сигналом| D[остаток s/ns]
    D --> C
Loading

Сравнение с аналогами

Возможность Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
Системные часы PSR-20 Паритет
Кэшированный UTC-экземпляр Clock
timestamp()/microtime() без объектов Clock
Реальный sleep() Clock + symfony/clock
sleep() переживает сигнал Clock

Clone this wiki locally