Skip to content

Feature Monotonic clock

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

📈 Монотонные часы — MonotonicClock

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

Время, которое никогда не идёт назад: NTP-коррекции и ручной перевод системных часов не влияют на показания.

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

При создании фиксируется пара «wall-момент + показание монотонного таймера ядра (hrtime)». Дальше now() вычисляется как точка отсчёта плюс монотонная дельта — системные часы больше не участвуют:

use CloudCastle\Clock\MonotonicClock;

$clock = new MonotonicClock('UTC');

$t1 = $clock->microtime();
// ... администратор перевёл системные часы на час назад ...
$t2 = $clock->microtime();

// $t2 > $t1 — всегда, без исключений.

Внутреннее состояние хранится в целых наносекундах — накопления ошибки плавающей точки на длинных интервалах нет.

Плюсы

  • Гарантированная монотонность: безопасен для тайм-аутов, дедлайнов, rate-limit окон.
  • Микросекундная стабильность на длинных интервалах (целочисленная арифметика).

Минусы

  • Показания могут расходиться с wall-часами после NTP-коррекций — это цена монотонности.
  • Каждый экземпляр имеет свою точку отсчёта: не сравнивайте моменты от разных экземпляров.

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

  • Вычисление тайм-аутов и дедлайнов: deadline = clock->microtime() + $timeout.
  • Как источник времени для Stopwatch-подобных замеров в своём коде.

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

  • Записывать MonotonicClock::now() в БД как «время события» — для этого системные часы.

Схема фичи

flowchart LR
    C[конструктор] -->|фиксирует| A["якорь: microtime(true) + hrtime()"]
    N["now()/microtime()"] --> D["якорь + (hrtime — якорь_hr)/1e9"]
    OS[(перевод системных часов)] -. не влияет .-> D
Loading

Жизненный цикл показаний

sequenceDiagram
    participant U as Код
    participant M as MonotonicClock
    participant K as Ядро (hrtime)

    U->>M: new MonotonicClock('UTC')
    M->>K: hrtime(true) — якорь
    U->>M: microtime()
    M->>K: hrtime(true)
    K-->>M: монотонная дельта
    M-->>U: якорь + дельта (всегда растёт)
Loading

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

Возможность Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
Монотонные часы Clock + symfony/clock
Целочисленное состояние (без дрейфа float) Clock
withTimezone() с новой точкой отсчёта Clock + symfony/clock

Clone this wiki locally