В сутках не всегда 24 часа, и почему мы храним время в UTC
Заметки

В сутках не всегда 24 часа, и почему мы храним время в UTC

Мы привыкли, что в сутках 24 часа. Но дважды в год это неправда: при переходе на летнее и на зимнее время один день длится 23 часа, другой - 25. Один час либо повторяется дважды, либо пропадает совсем. Мелочь, из-за которой ломается на удивление много.

Что из-за этого едет

  • Логика "прошло ровно 24 часа" в такой день ошибается на час.
  • Задача по расписанию, назначенная на время внутри пропавшего часа, не запускается вообще; назначенная на повторяющийся час - запускается дважды.
  • Расчёты "сколько отработано за сутки", "конец дня", "на сколько сдвинуть" - всё тихо уезжает.

Это не теория. На одном живом проекте мы на такой сдвиг и налетели - ровно на разнице между "24 часа" и "одни календарные сутки". С тех пор относимся ко времени с уважением.

Почему выручает UTC

UTC - это единые всемирные часы, у которых нет перевода на летнее время. В UTC сутки всегда ровно 24 часа, час никогда не повторяется и не пропадает. Поэтому всё время внутри системы - в базе, в расчётах, в сравнениях - мы храним и считаем в UTC. Там арифметика времени честная и предсказуемая.

Есть и вторая причина. Местное время - вещь политическая: страны меняют правила перевода часов, сдвигают пояса, вводят и отменяют летнее время. Если хранить "10:00 по местному", через год уже нельзя точно сказать, какому мировому моменту это соответствовало. UTC не меняется никогда - это надёжная точка отсчёта, к которой всегда можно привязаться.

Часовой пояс - только на экране

Пользователю, конечно, нужно видеть своё местное время, а не UTC. Поэтому перевод в часовой пояс мы делаем в самый последний момент - при выводе на экран. Внутри всё живёт в UTC, а "10:00 по Киеву" появляется только там, где на время смотрит человек.

Совет

Храни и считай момент времени в UTC, переводи в часовой пояс только при выводе. Тогда странность с 23 и 25 часами остаётся на самом краю системы, где ей и место.

Мелочь, которая избавляет от целого класса плавающих багов "то на час, то не в тот день".

Александр

Александр

Fullstack-разработчик с 8+ годами опыта - от промышленной автоматизации и работы с оборудованием до электронного документооборота и чат-ботов. Сейчас фокус на прикладном ИИ - от RAG-платформ для диалоговых ботов до компьютерного зрения.