Почему формат даты и времени не должен включать временную зону?
sanmai opened this issue · 4 comments
Не объяснено, почему формат даты и времени не должен включать временную зону.
Объяснение для обратного требования есть:
Временные зоны постоянно меняются, как в будущем, так и задним числом. Например, человек просит чтобы его в девять утра разбудили через год. Вы посчитали сколько это будет по UTC сейчас и записали, а за год в той временной зоне появилось или пропало летнее время, и вы разбудили человека не в девять, а в десять. Это ошибка, которую можно было предотвратить с минимальными затратами усилий и времени, если не следовать рекомендации хранить время строго по UTC.
Также не понятно, почему нельзя использовать new \DateTime()
@movetz выносим получение времени в функцию-обертку, а при тестах ее подменяем и крутим время в любую сторону
@sanmai если на сервере всегда работать с нулевой зоной, а любые входящие запросы сначала к ней приводить, это имеет смысл. если так - акцентировать на это внимание в документе
Вопрос требует очень долгого введения в то, что такое время и как оно работает. Я это опущу и попробую просто кратко ответить тезисами. Возможно этого будет достаточно для большинства, кому этот вопрос интересен.
Плюсы хранения всех дат в одной зоне (UTC0).
- Уменьшение кол-ва кода, который работает с датами. Достаточно при получении даты от внешнего источника привести ее в нужный формат (на уровне парсинга запроса) и дальше по коду вообще не задумываться об этом, зная, что все даты внутри кода и во внутренней базе имеют одинаковый формат
- Удобство при дебаге: можно спокойно грепнуть какой-то лог на
2018-01-01 01
и быть уверенным, что в вывод попадут все записи за 1 января 1 час ночи по UTC0. Если же все даты в разных форматах, то грепнуть будет сложно. - Удобство при выполнении SQL запросов. Можно писать substr на даты и получать очень дешево срезы по дню, неделе, месяцу и т.п. не задумываясь о зонах.
- Аналогичный профит и в PHP коде. Часто можно не переводить дату из строки в объект и просто получить день/месяц/год прямо из строки.
- Удобство для людей, которые читают данные. Можно пробежаться глазами по датам. Если же у каждой даты высматривать ее таймзону и делать в голове вычисления, то это становится очень долгим процессом.
- Это бесплатно и не требует никаких дополнительных усилий.
Минусы:
- Есть искусственный кейс, который может потребовать лишнего телодвижения: если надо задать точку времени в будущем, но чтобы эта точка двигалась, если правительство двигает зоны (совсем не обязательно, что пользователю надо, чтобы точка двигалась). То есть речь о том, что в требованиях должна быть именно прописана привязка к «солнечному дню», а не к абсолютному времени. В такой ситуации действительно надо сохранить желаемое смещение по «солнечному дню» в отдельную колонку. Но это в то же время вполне разумно. Если это «смещение» является частью продуктовых требований, то нет криминала в том, что для него есть отдельная колонка в явном виде. Продуктовая команда может захотеть работать с этой колонкой для аналитики и т.п.
Итого: пока что не вижу причины хранить в каждой колонке с датой какую-либо зону, кроме UTC0. Возможно есть какие-то другие кейсы, возможно я что-то не понял. Если так, то пишите, вопрос важный и интересный.
Также не понятно, почему нельзя использовать new \DateTime()
В целом выше правильно ответили. Обычное базовое требование. Без этого нельзя будет написать тесты.