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

CloudCastle Clock

Часы для PHP 8.1+ поверх PSR-20: пять реализаций, три декоратора и три инструмента интеграции — самый полный набор среди PSR-20-пакетов, с жёсткой валидацией ввода и производительностью в группе лидеров.

Навигация

Установка

composer require cloudcastle/clock

Быстрый старт

use CloudCastle\Clock\SystemClock;

$clock = SystemClock::utc();          // продакшн: PSR-20 часы (кэшированный экземпляр)
$clock->now();                        // DateTimeImmutable
$clock->timestamp();                  // int — без создания объектов
$clock->microtime();                  // float — секунды.микросекунды
use CloudCastle\Clock\MockClock;

$mock = MockClock::from('2026-01-01 00:00:00', 'UTC');
$mock->sleep(3600.0);                 // тест: мгновенно, +1 час виртуального времени
$mock->now()->format('H:i');          // 01:00
use CloudCastle\Clock\Clock;
use CloudCastle\Clock\ClockHolder;

ClockHolder::set($mock);              // легаси без DI: одна точка подмены времени
Clock::now();                         // читается из любого места приложения
ClockHolder::reset();

Полные сценарии — на страницах возможностей, каждая с примерами, схемой и жизненным циклом.

Архитектура пакета

flowchart TB
    PSR["Psr\\Clock\\ClockInterface (PSR-20)"] --> CI["ClockInterface<br/>+timestamp() +microtime()<br/>+timezone() +withTimezone()"]
    CI --> SLP["SleepableClockInterface<br/>+sleep() +sleepUntil()"]
    CI --> ADJ["AdjustableClockInterface<br/>+setTo() +modify()<br/>+advance() +rewind()"]

    SLP -.-> SC[SystemClock]
    ADJ -.-> FC[FrozenClock]
    ADJ -.-> MC[MockClock]
    SLP -.-> MC
    CI -.-> MO[MonotonicClock]
    CI -.-> CB[CallbackClock]

    subgraph Декораторы
        OC[OffsetClock]
        SCL[ScaledClock]
        TC[TruncatingClock]
    end
    CI -.-> OC & SCL & TC
    OC & SCL & TC -->|оборачивают| CI

    subgraph Интеграция
        H[ClockHolder + фасад Clock]
        T[ClockAwareTrait]
        W[Stopwatch]
    end
    H --> CI
    T --> H
Loading

Жизненный цикл времени: прод и тест

sequenceDiagram
    participant S as Сервис
    participant T as ClockAwareTrait
    participant H as ClockHolder
    participant P as SystemClock (прод)
    participant M as MockClock (тест)

    rect rgb(235, 245, 235)
    note over S,P: Продакшн
    S->>T: now()
    T->>H: get()
    H->>P: now()
    P-->>S: реальный момент
    end

    rect rgb(235, 240, 250)
    note over S,M: Тест
    S->>T: setClock(MockClock)
    S->>T: now()
    T->>M: now()
    M-->>S: виртуальный момент
    S->>M: sleep(3600) — мгновенно
    end
Loading

Строгость контроля качества

Уровни статических анализаторов и порогов пакета против аналогов — значения подставляются из конфигов автоматически:

Сгенерировано из конфигов пакета (composer docs:sync). Уровни Clock — из phpstan.neon / psalm.xml / infection.json.dist / phpmd.xml / deptrac.yaml; по аналогам — заявленный инструментарий из их composer.json (Composer-дистрибутивы аналогов конфигов качества не содержат, поэтому их уровни — «н/д»).

Контроль качества Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
PHPStan ✅ level max + strict-rules ✅ (уровень: н/д) ✅ (уровень: н/д) ✅ (уровень: н/д) ✅ (уровень: н/д) Clock (уровень задокументирован)
Psalm ✅ errorLevel 1 ✅ (уровень: н/д) Clock (уровень задокументирован)
Мутационное тестирование (Infection) ✅ minMSI 98% (факт: 0 выживших) ✅ (уровень: н/д) ✅ (уровень: н/д) Clock (уровень задокументирован)
PHPMD ✅ 10 правил ✅ (уровень: н/д) Clock (уровень задокументирован)
Deptrac (архитектурные слои) ✅ 5 слоёв Clock
Rector (dry-run в CI) ✅ (уровень: н/д) Clock (уровень задокументирован)
Код-стайл (PSR-12: phpcs + cs-fixer) ✅ (уровень: н/д) ✅ (уровень: н/д) Clock (уровень задокументирован)
Покрытие строк (порог на файл) 98% (факт: 100%) н/д н/д н/д н/д н/д Clock
Конфиги качества в дистрибутиве ✅ поставляются Clock

Сравнение возможностей с аналогами

Таблицы генерируются автоматически (composer docs:sync): факты поддержки — из tools/features-data.php, победитель вычисляется по этим фактам.

Сгенерировано из tools/features-data.php (факты о поддержке). Легенда: ✅ полностью · ⚠️ частично · 🔌 адаптер · ❌ нет · — неприменимо.

Реализации часов

Функция Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
Системные часы (PSR-20) Паритет
Замороженные часы ⚠️ Clock + symfony/clock + lcobucci/clock + beste/clock + ergebnis/clock
Тестовые часы с виртуальным sleep() Clock + symfony/clock
Монотонные часы (hrtime) Clock + symfony/clock
Часы на callback Clock
Масштабируемое время (быстрее/медленнее) Clock
Часы со смещением (прошлое/будущее) Clock
Усечение моментов (сек/мин/час/сутки) ⚠️ Clock

Управление временем в тестах

Функция Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
Точная установка момента (setTo) ⚠️ ⚠️ Clock
Сдвиг строкой-модификатором (modify) ⚠️ Clock + symfony/clock
Сдвиг вперёд/назад интервалом или секундами ⚠️ ⚠️ Clock
Виртуальный sleepUntil(момент) Clock

Интеграция в приложение

Функция Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
Расширенный контракт: timestamp()/microtime() без объектов Clock
Смена таймзоны withTimezone() ⚠️ Clock + symfony/clock
Глобальный слот часов приложения ⚠️ Clock + symfony/clock
Трейт внедрения часов в сервисы Clock + symfony/clock
Секундомер на монотонном таймере 🔌 Clock
DatePoint: момент от часов приложения с исключениями ⚠️ Clock + symfony/clock
Адаптер стороннего PSR-20 к расширенному контракту Clock + beste/clock
freeze(): снимок любых часов в управляемые ⚠️ Clock
Хелпер now(«+1 hour») с модификатором Clock + symfony/clock + nesbot/carbon

Надёжность и безопасность

Функция Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
Типизированные исключения валидации ⚠️ ⚠️ Clock
Отклонение null-байтов во вводе Clock
Экранирование управляющих символов в ошибках Clock
Реальный sleep() переживает прерывание сигналом Clock

Производительность

Изолированные замеры (composer compare): отдельный процесс на каждую пару «библиотека × сценарий», одинаковые циклы, медиана из 5 прогонов, без Xdebug. Отрыв меньше 2 % — «Паритет лидеров».

Сгенерировано из composer compare (PHP 8.1.34). Правки в блоке будут перезаписаны.

Сценарий Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
now() в системной таймзоне 648 611 ops/s 592 125 ops/s 650 011 ops/s 99 591 ops/s 81 644 ops/s 649 211 ops/s Паритет лидеров
now() в UTC 643 127 ops/s 586 970 ops/s 642 473 ops/s 640 540 ops/s 173 049 ops/s 639 452 ops/s Паритет лидеров
чтение зафиксированного момента 22 262 011 ops/s 6 678 993 ops/s 22 706 907 ops/s 9 074 581 ops/s 29 451 ops/s 22 472 910 ops/s Паритет лидеров
задача: unix-время текущего момента 813 138 ops/s 568 078 ops/s 609 675 ops/s 608 764 ops/s 170 630 ops/s 610 357 ops/s Clock
задача: метка времени с микросекундами 800 739 ops/s 447 005 ops/s 487 861 ops/s 480 447 ops/s 146 079 ops/s 479 579 ops/s Clock
задача: сдвиг виртуального времени на 1 с (тесты) 941 497 ops/s 275 647 ops/s 71 448 ops/s Clock
создание часов + первый now() 97 241 ops/s 92 239 ops/s 96 489 ops/s 98 468 ops/s 77 991 ops/s 97 054 ops/s Паритет лидеров

Память — добавленная пиковая память процесса за сценарий (классы библиотеки + объекты + операции), меньше — лучше:

Сценарий Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
now() в системной таймзоне 0.0 КБ 0.0 КБ 0.0 КБ 0.0 КБ 3 521.9 КБ 0.0 КБ Паритет лидеров
now() в UTC 0.0 КБ 0.0 КБ 0.0 КБ 0.0 КБ 3 521.9 КБ 0.0 КБ Паритет лидеров
чтение зафиксированного момента 0.0 КБ 0.0 КБ 0.0 КБ 0.0 КБ 3 521.9 КБ 0.0 КБ Паритет лидеров
задача: unix-время текущего момента 0.0 КБ 0.0 КБ 0.0 КБ 0.0 КБ 3 521.9 КБ 0.0 КБ Паритет лидеров
задача: метка времени с микросекундами 0.0 КБ 0.0 КБ 0.0 КБ 0.0 КБ 3 521.9 КБ 0.0 КБ Паритет лидеров
задача: сдвиг виртуального времени на 1 с (тесты) 0.0 КБ 0.0 КБ 3 521.9 КБ Паритет лидеров
создание часов + первый now() 0.0 КБ 0.0 КБ 0.0 КБ 0.0 КБ 3 521.9 КБ 0.0 КБ Паритет лидеров

Итог

Подробное заключение с плюсами, минусами и рекомендациями по выбору — на странице Сравнение.

Ссылки

Clone this wiki locally