Данная статья была написана мной при работе в компании. Будет полезна для понимания времени разработчикам и аналитикам, а также для организации контрактов как best practice. Как выяснилось на практике, далеко не все представляют себе часовые пояса в разработке.
Команда работала с фреймворком Angular, ввиду этого будет он и упомянут. Утверждения правдивы и для React/Vue/… в схожих кейсах.
Небольшой голоссарий:
-
пайп (pipe) в Angular — функция приобразования в шаблоне; стоит понимать как чистую функцию
-
TZ — time zone — часовой пояс
-
DRY — don’t repeat yourself
Ввиду сильного раздрая и неясности работы frontend и backend с датами и временем, были вынесены на обсуждение следующие договоренности.
Очень рекомендую к прочтению:
|
Утверждение |
Обоснование |
|---|---|
|
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, подписки на измененные статусы и события и др.
Дано:
-
Компонент (Component) с шаблоном (html)
-
Сервер (backend)
-
formatVar = «DD.MM.YYYY HH:mm»
-
offsetVar = время клиента «+03:00» (предположим что лежит на клиенте, может приходить с сервера в том же запросе)
Путь отображения без промежуточных звеньев:
-
Component делает запрос на backend, приходит:
-
date: «2020-11-17T15:06:47.523Z» => переменная dateVar
-
-
Component сохраняет данные в переменные
-
В шаблоне (html) в блок (div) через интерполяцию вставляется переменная + angular date pipe
-
dateVar | date : formatVar : offsetVar (см. Дано)
-
вывод => 2020.11.17 18:06
-
-
Пользователь меняет переменную dateVar на 2020.11.17 20:00
-
Пользователь жмет «Сохранить»
-
Component преобразует дату к формату iso-string (стоит уточнить условия на практике, т.к. на момент написания статьи были нюансы)
-
если из FormControl поступает iso-string с указанием часового пояса, то формат готов
-
если из FormControl поступает string без часового пояса, то тут возможны варианты, но по факту все сведется к `new Date(var съедобного формата с часовым поясом).toISOstring()`
-
-
Component отправляет данные на backend в формате iso-string с TZ
ссылка на оригинал статьи https://habr.com/ru/articles/736224/
Добавить комментарий