Привет.
Прочел достаточно статей на тему, примерно понял систему, что храним в UTC, но хотел бы пару моментов уточнить.
Сервер, например, работает в Москве, а его пользователи по всей стране. Каждый пользователь в своем личном кабинете может установить себе личную временную зону (ЛВЗ далее) .
Такие вопросы:
1) В php приложении, в бутстрапе, не стоит в date_default_timezone_set() устанавливать эту ЛВЗ пользователя? Т.к. это будет аффектить все другие подсистемы, типа логов.
2) В БД, mysql, установка временной зоны по умолчанию в UTC считается нормой?
3) Использовать ли тип TIMESTAMP, который хранит в базе время в UTC (что и хотели), а временную зону в БД будем в бутстрапе устанавливать в значение равное ЛВЗ пользователя? Дата будет прилетать в базу, как клиент ввел.
Но если учесть пункт 1), то зоны в разных частях приложения будут отличаться.
4) Может использовать тип DATETIME , куда перед сохранением, и выборками, всегда конвертить дату из ЛВЗ в UTC, и обратно?
5) Какие главные минусы против чтобы временную метку хранить просто как число unixtimestamp? То что выборки , когда нужны всякие DATE специфичные функции, потребуют преобразования в тип дату в каждой строке? (это преобразование может не сложное?, ведь datetime и так хранится как число)
UTC позволит поднять второй сервер во Владивостоке или в заграничном облаке и не запутаться, например...
А временные зоны нужны только на фронте.
Соответственно, переход из UTC и обратно - между фронтом и бэком (весь бэк в UTC).
В теории.
На практике - если у вас где-то в форме заполняется тупо дата, а сайт работает в 12 часовых поясах, вам придется придумать, как в этих датах, которые в другом часовом поясе будут другими, не создать неконсистентность. Например, принять правило, что даты - по Москве. Или везде оперировать временем с точностью до часа.
Проблем с временными зонами вообще не будет, если их представление выдавить максимально ближе к модели представления данных на интерфейсе пользователя.
Нужно конвертировать в строку только непосредственно перед отрисовкой дату и время из UTC, и обратно загонять время в UTC, если забираете пользовательский ввод.
Весь бек должен работать в одной временной зоне, а от пользователя знать, что он в такой-то временной зоне, только в контексте сессионной переменной, если это необходимо.
Когда я начинал изучение языков программирование, ко мне пристала одна проблема, из-за которой мне говорили, что я полный нуб.
Я время, в базе, хранил как метку в секундах, да и до сих пор так делаю. А если надо в человеко-понятный уровень превратить, так в PHP есть date(), и в js new Date()
А когда хранят в базе что-то подобное 2025-01-31t12:55:43, то это какой-то мрак.
Конечно, такой подход убирает сложность работы с датами, но я люблю, когда дата представлена как 31 янв 12:55, причем год должен появиться только тогда, когда нынешний и в дате сохранения не совпали.
Да, это лишняя обработка на фронте, но ведь красиво же и еще доступней для пользователей.
А теперь к сути вопроса.
1. Сервер должен иметь постоянный часовой пояс. Клиенту отправлять даты именно в этом часовом поясе. Я бы выбрал нулевой пояс. Просто мне проще в голове представлять как отнимать или прибавлять.
2. На клиенте обрабатывать данные и выставлять часовой пояс соответствуя данным из браузера.
3. Если такая настройка есть, чтобы пользователь изменил часовой пояс, то тут должен произойти просто пересчет и всё.
У вас, на клиенте, должен быть объект js, который должен хранить некоторые глобальные настройки аккаунта, которые должны всегда загружаться вместе со страницей.
А когда хранят в базе что-то подобное 2025-01-31t12:55:43, то это какой-то мрак.
Если в БД дата-время хранится именно в показанной форме, т.е. в поле строкового типа, то и в самом деле создателя такого бреда есть смысл подозревать в наличии альтернативного мышления.
Но если в БД дата-время хранится в поле типа DATETIME / TIMESTAMP, то написанное вами - это строковое представление значения, сделанное вашим кодом (или используемым клиентом), и вам необходимо уделить время понимаю разницы между хранением и отображением.
Я время, в базе, хранил как метку в секундах, да и до сих пор так делаю. А если надо в человеко-понятный уровень превратить, так в PHP есть date(), и в js new Date()
Однако зоны времени, как ни крути, существуют... для какой зоны вы сохраняли значение? где и когда приводили его к локальному времени клиента и наоборот?
Я уж не говорю о том, что вы при таком хранении однозначно теряете встроенные средства СУБД для обработки временнЫх данных, и, как следствие, производительность.
Akina, если использовать не datetime / timestamp а просто big int, то смещения уже не будет существовать
чисто интересно ты же вроде опытный, вот я работаю постоянно с датами через биг инт, и все даты - временные метки timestamp - как думаешь исходя из твоего опыта - плохой ли это подход ?
просто интересно мнение эксперта который 15+ лет в базами возиться