Работа с датой и временем

Ноябрь, 2023

Возможно, данная тема немного холиварна и существуют кейсы, когда рекомендация неприменима, но для большинства совет будет такой:

В backend-е всегда храни и работай с датой и временем в UTC (UTC±0).

Часто разработчик использует зону в которой находится он сам или его сервер и поначалу всё работает отлично. Но как только появляются пользователи с другой временной зоной, то возникает вопрос, как с этим работать?

Предположим, что на сайте публикуется online-мероприятие, например, вебинар, у которого есть дата и время проведения. Участниками могут быть люди со всего мира и указать для всех 10 декабря 20:00 нельзя, потому что для каждого часового пояса время будет разное, надеюсь "почему" объяснять не надо.

Как это обычно работает:

На сервере все даты хранятся в UTC, независимо от временной зоны пользователя и сервера (речь про физическое расположение, а не настройки сервера). Любые манипуляции с датами происходят именно в этой зоне.

Далее есть два варианта:

  • если API, то возвращаем данные и клиент отображает дату с учётом текущей временной зоны пользователя.
  • если у нас обычный MPA, то мы должны предварительно получить от клиента его временную зону и конвертировать дату на уровне представления (например, в blade).

Клиент в свою очередь отправляет дату тоже в UTC или вместе с тайм-зоной и сервер сам конвертирует в UTC.

Таким образом, мы даём клиенту или представлению полную свободу по отображению даты с простой возможностью конвертации в любую другую тайм-зону. Это же касается и формата даты - хранить в рекомендуемом формате СУБД, а на клиенте приводить к необходимому формату (форматы так же зависят от локации пользователя).

Представим ещё одну ситуацию - есть много серверов по всему миру, у каждого своё локальное время и пользователи создают новые мероприятия и указывают своё локальное время. Если потребуется чтобы сервера общались между собой, то придётся хранить и передавать таймзону и конвертировать в локальное.

Если мы по умолчанию храним в UTC, то ничего больше не требуется, просто возвращаем время клиенту, который уже отобразит с учётом локального времени пользователя.

Можно подумать, что достаточно придерживаться всегда одной любой тайм-зоны, но во-первых очевидно, что удобнее использовать нулевую, это универсальный, принятый и понятный формат везде. Во-вторых, если мы работаем с временными метками (Unix time), то они, как известно, всегда в UTC.

Ещё немного информации можешь найти в статье « Always Use UTC Dates And Times » или погуглив самостоятельно.