--- status: рекомендуемая --- # Время Один формат времени на всё приложение: хранение, логи, API, обмен с внешними системами. Разные форматы в разных слоях — источник ошибок, которые всплывают через полгода на границе перехода на летнее время. ## Формат - **RFC 3339, UTC, суффикс `Z`**: `2026-06-28T11:23:45Z`. - **Ширина фиксируется на каждый носитель** и внутри него не плавает. Лексикографическая сортировка равна хронологии только среди строк одинаковой длины: `…00.123Z` сортируется раньше `…00.12Z`, хотя хронологически позже. Ради этого формат и фиксируется — `ORDER BY created_at` по текстовому полю обязан давать порядок событий. - Разные носители могут иметь разную точность: строки БД и строки лога между собой никогда не сравниваются. Требование — не «одна точность на приложение», а «внутри колонки и внутри потока логов ширина одна». - Локальное время не хранится и не передаётся **нигде** — ни в БД, ни в логах, ни в JSON API. ## Генерирует приложение, а не хранилище - Единая точка получения «сейчас» и единая точка форматирования и разбора — как с идентификаторами (`arch/db-identifiers.md`). Прямые вызовы часов по коду не разбросаны: иначе ни формат, ни зона не гарантированы. - **Дефолты в схеме БД не используем.** Забытая вставка `created_at` должна падать громко, а не тихо получать значение от БД — иначе расходятся источник времени (сервер БД) и его формат. ## Длительность — не метка времени Измерение длительности операции — отдельная величина: число (обычно миллисекунды) в поле вида `duration_ms`, а не разность двух меток и не время в формате выше. Засекает её тот слой, который делает вызов. **Интервал измеряется монотонными часами процесса**, а не вычитанием сохранённых меток: стенные часы подводит NTP, они могут шагнуть назад и дать отрицательную длительность. Из этого следует, что источник меток времени и источник интервалов — разные, даже если оба называются «часы». ## Зоны Единственное место, где появляется не-UTC, — **отображение пользователю**. Зона берётся из конфигурации (`arch/config.md`), значение по умолчанию — `UTC`. На хранение, сортировку и логи она не влияет. Если бизнес-логика оперирует календарными сущностями («сегодня», «за месяц»), зона указывается **явно** в месте вычисления — молчаливое использование системной зоны процесса запрещено: она разная на ноутбуке и в контейнере. По умолчанию это та же зона, что и для отображения; если календарная логика требует другой, это записывается явно. Конвенция описывает фиксацию **свершившихся моментов**. Планирование будущих событий — отдельный случай (там хранят локальное время плюс имя зоны, потому что правила зон меняются); пока такой сущности нет, правило не формулируем. ## Связано - `arch/config.md` — где задаётся зона отображения. - `arch/db-identifiers.md` — то же правило «генерирует приложение» для id.