-
Notifications
You must be signed in to change notification settings - Fork 0
Feature Frozen clock
github-actions[bot] edited this page Jul 14, 2026
·
1 revision
Время стоит, пока его явно не сдвинут. Главный инструмент детерминированных тестов.
Часы хранят один момент и отдают его из now() без изменений. Сдвиг — только
явными методами контракта AdjustableClockInterface: setTo(), modify(),
advance(), rewind().
use CloudCastle\Clock\FrozenClock;
$clock = FrozenClock::from('2026-01-01 12:00:00', 'UTC');
$clock->now(); // всегда 2026-01-01 12:00:00
$clock->advance(90.0); // +1.5 минуты (секунды с дробью — до микросекунды)
$clock->advance(new DateInterval('P1D'));
$clock->modify('next monday');
$clock->rewind(0.000001); // -1 мкс
$clock->setTo(new DateTimeImmutable('2030-01-01'));Фабрики: from() (строка или объект + необязательная зона), fromNow(),
fromUtcNow(). Мусорные строки моментов и модификаторов отклоняются
InvalidClockValueException — включая строки с null-байтами, которые
встроенный парсер PHP молча усёк бы.
- Полный контроль времени в тестах: никаких
sleep()и флаков. - Микросекундная точность сдвигов в обе стороны.
- Жёсткая валидация ввода — инъекции строк в модификаторы не проходят.
- Мутабельные часы: не делите один экземпляр между независимыми потребителями, если они не должны видеть сдвиги друг друга.
- Фиксировать «сегодня» в тестах тарифов, расписаний, сроков действия.
- Проверять граничные моменты: полночь, конец месяца, переход DST.
-
FrozenClockв проде — время «застынет» со всеми вытекающими. - Сдвигать время строкой там, где хватает
advance(seconds): строка медленнее и её нужно парсить.
flowchart LR
IN["from(строка/объект, зона)"] --> FC[FrozenClock]
FC -->|"now() — всегда один момент"| M[DateTimeImmutable]
stateDiagram-v2
[*] --> Заморожен: from()/fromNow()/fromUtcNow()
Заморожен --> Заморожен: now() — тот же момент
Заморожен --> Сдвинут: advance()/rewind()
Заморожен --> Сдвинут: modify("+1 day")
Заморожен --> Сдвинут: setTo(момент)
Сдвинут --> Заморожен: новый фиксированный момент
Заморожен --> Отклонено: мусор/NUL в строке
Отклонено --> [*]: InvalidClockValueException
| Возможность | Clock | symfony/clock | lcobucci/clock | beste/clock | nesbot/carbon | ergebnis/clock | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Замороженные часы | ✅ | ✅ | ✅ | ✅ | ✅ | Clock + symfony + lcobucci + beste + ergebnis | |
setTo() точная установка |
✅ | ❌ | ❌ | ❌ | Clock | ||
modify() строкой |
✅ | ✅ | ❌ | ❌ | ❌ | Clock + symfony/clock | |
advance()/rewind() интервалом и секундами |
✅ | ❌ | ❌ | ❌ | Clock | ||
| Валидация модификаторов с null-байтами | ✅ | ❌ | — | — | ❌ | — | Clock |
CloudCastle Clock · · PHP 8.1+
GitHub · Packagist · Releases · Discussions · Issues
Email · Telegram · VK · Сетка · 💜 Поддержать проект
Исходники Wiki — каталог wiki/ в репозитории (синхронизация через GitHub Actions)