-
Notifications
You must be signed in to change notification settings - Fork 0
Feature System clock
github-actions[bot] edited this page Jul 14, 2026
·
1 revision
Продакшн-реализация 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]
flowchart TD
A["sleep(seconds)"] --> B["Duration::splitSeconds<br/>валидация ≥ 0"]
B --> C["time_nanosleep(s, ns)"]
C -->|завершился| E[возврат]
C -->|прерван сигналом| D[остаток s/ns]
D --> C
| Возможность | Clock | symfony/clock | lcobucci/clock | beste/clock | nesbot/carbon | ergebnis/clock | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Системные часы PSR-20 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Паритет |
| Кэшированный UTC-экземпляр | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Clock |
timestamp()/microtime() без объектов |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Clock |
Реальный sleep()
|
✅ | ✅ | ❌ | ❌ | ❌ | ❌ | Clock + symfony/clock |
sleep() переживает сигнал |
✅ | ❌ | — | — | — | — | Clock |
CloudCastle Clock · · PHP 8.1+
GitHub · Packagist · Releases · Discussions · Issues
Email · Telegram · VK · Сетка · 💜 Поддержать проект
Исходники Wiki — каталог wiki/ в репозитории (синхронизация через GitHub Actions)