Единый формат времени для приложения

от автора

Данная статья была написана мной при работе в компании. Будет полезна для понимания времени разработчикам и аналитикам, а также для организации контрактов как best practice. Как выяснилось на практике, далеко не все представляют себе часовые пояса в разработке.

Команда работала с фреймворком Angular, ввиду этого будет он и упомянут. Утверждения правдивы и для React/Vue/… в схожих кейсах.

Небольшой голоссарий:

  • пайп (pipe) в Angular — функция приобразования в шаблоне; стоит понимать как чистую функцию

  • TZ — time zone — часовой пояс

  • DRY — don’t repeat yourself

Ввиду сильного раздрая и неясности работы frontend и backend с датами и временем, были вынесены на обсуждение следующие договоренности.

Очень рекомендую к прочтению: 

  1. https://habr.com/ru/post/146109/

  2. https://ru.wikipedia.org/wiki/%D0%92%D1%81%D0%B5%D0%BC%D0%B8%D1%80%D0%BD%D0%BE%D0%B5_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%B2%D1%80%D0%B5%D0%BC%D1%8F — что такое UTC, GMT

Утверждение

Обоснование

1. Общение фронта с бэком всегда в формате iso-string с указанием часового пояса в формате UTC (Z — метка нулевого часового пояса)

— время в базе данных (должно) хранится в UTC по 0 поясу (не важно это iso-string или timestamp)

— при получении даты с часовым поясом, отличным от 0, время, сохраняемое в базу, будет преобразовано к 0 часовому поясу

— единый формат и шкала измерения данных предупреждают ошибки

— UTC = международный, признанный формат данных

— международная космическая станция использует UTC в качестве эталона времени

2. Временные метки для данных везде где возможно брать на сервере, а не со стороны клиента

— время клиента далеко не всегда совпадает со временем сервера (имеется ввиду не часовой пояс UTC)

— время клиента не всегда правдиво (неправильное время)

3. Смещение по временному поясу для местного времени должно быть доступно в виде параметра смещения

Пример: «+180» = «+03:00» = TZ Москва

— стандартный date pipe angular’а используют смещение для вывода данных

— позволяет соблюсти формат UTC при общении с сервером

Нужно уточнить формат смещения. Стандартно предполагается два варианта: 

— number ( смещение в часах «(+/-)  * 60»)

— string (пример, Москва — «+03:00»)

Формат типа string используется в смещении времени date pipe в виде как есть (пример: «timeVar | date: «DD:MM:YYYY HH:mm : «+03:00» => 01.01.2020 11:32; UTC — 01.01.2020 08:32).

4. На фронте оптимизировать правильный формат вывода данных в константу

Пример: «DD:MM:YYYY HH:mm»

— унификация и выполнения принципа DRY

5. Для преобразование времени на вывод использовать единый пайп

— унификация и выполнения принципа DRY

6. Использование единого формата iso-string (в UTC) по всему приложению при общении между сущностями

— единый формат и шкала измерения данных предупреждают ошибки

— перевод из iso-string в формат объекта данных просто написать самостоятельно или использовать библиотеку

— iso-string «кушают» все (обязательно нужно помнить про указание часового пояса)

Далее пример с использованием Angular (в целом будет понятен без знания)

  • Component — некая сущность с логикой (в примере — .ts файл)

  • Шаблон — html-файл, соединённый с Component

  • Интерполяция в Angular — механизм привязки переменной шаблона и логики (в примере: Component и шаблона; ссылка на определение)

  • FormControl — элемент Angular Forms; класс с методами set, get, подписки на измененные статусы и события и др.

Дано: 

  1. Компонент (Component) с шаблоном (html)

  2. Сервер (backend)

  3. formatVar = «DD.MM.YYYY HH:mm»

  4. offsetVar = время клиента «+03:00» (предположим что лежит на клиенте, может приходить с сервера в том же запросе)

Путь отображения без промежуточных звеньев:

  1. Component делает запрос на backend, приходит:

    • date: «2020-11-17T15:06:47.523Z» => переменная dateVar

  2. Component сохраняет данные в переменные

  3. В шаблоне (html) в блок (div) через интерполяцию вставляется переменная + angular date pipe

    • dateVar | date : formatVar : offsetVar (см. Дано)

    • вывод => 2020.11.17 18:06

  4. Пользователь меняет переменную dateVar на 2020.11.17 20:00

  5. Пользователь жмет «Сохранить»

  6. Component преобразует дату к формату iso-string (стоит уточнить условия на практике, т.к. на момент написания статьи были нюансы)

    • если из FormControl поступает iso-string с указанием часового пояса, то формат готов 

    • если из FormControl поступает string без часового пояса, то тут возможны варианты, но по факту все сведется к `new Date(var съедобного формата с часовым поясом).toISOstring()`

  7. Component отправляет данные на backend в формате iso-string с TZ


ссылка на оригинал статьи https://habr.com/ru/articles/736224/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *