Как решать проблему работы с разными часовыми поясами в распределенной команде
Что проверяют
Вопрос двойной: как вы работаете в команде, разбросанной по часовым поясам, и не ломается ли время в коде, который такая команда пишет. Уточните в начале, что важнее собеседнику. Следом часто спрашивают, как устроить ревью и дежурства, когда общих рабочих часов всего два-три.
Как отвечать
Организационная часть опирается на ваш опыт: приведите свой пример с цифрами, сколько было поясов, сколько часов пересечения, что изменилось после ваших договорённостей. Каркас:
- асинхронность по умолчанию: решения фиксируются письменно в задаче, дизайн-документе или ADR, а не остаются в устном созвоне;
- окно пересечения: общие часы под синхронные встречи, остальное время без созвонов;
- договорённость по ревью: срок ответа на pull request, чтобы изменение не стояло сутки из-за разницы во времени;
- дежурства: график, где каждый дежурит в свои дневные часы.
Если в распределённой команде вы не работали, скажите честно и опишите, как организовали бы процесс, опираясь на опыт работы со смежными командами.
Техническая часть на Go:
- хранить в UTC:
time.Now().UTC()в логах и событиях, в PostgreSQL колонкиtimestamptz, наружу форматtime.RFC3339; - зону пользователя применять при показе:
time.LoadLocation("Europe/Moscow")иt.In(loc). Нужны идентификаторы IANA, а не смещения вроде+03:00, иначе переход на летнее время в других странах ломает расчёт; - база зон в контейнере: в образе
scratchили distroless нет/usr/share/zoneinfo, иLoadLocationвернёт ошибку. Решение:import _ "time/tzdata"или тег сборкиtimetzdata, база встраивается в бинарник.
Где спотыкаются
Сравнивают time.Time через ==. Оператор учитывает зону и показания монотонных часов, поэтому один и тот же момент может оказаться «разным». Нужен t.Equal(u).
Планируют крон в локальном времени сервера. В ночь перевода часов задача пропускается или выполняется дважды.
Отвечают только про пакет time, когда спрашивали про людей, или наоборот. Покажите обе стороны и спросите, какая интересует больше.