Сохранение и отчетность информации о датах и часовых поясах в базе данных, когда данные зависят от даты и времени
Было довольно много вопросов о сохранении информации о датах и часовых поясах в БД, но больше на общем уровне. Здесь я хотел бы обратиться к конкретному случаю.
Технические характеристики системы
У нас есть база данных CRM системы
Это мультитенантная система, в которой арендаторы могут использовать настройку своего часового пояса (это установка только одного часового пояса для каждого арендатора, сохраненного в таблице арендаторов один раз и никогда не изменяющегося)
- Все временные метки, сохраненные в UTC в БД
- Бизнес-правило должно быть охвачено в БД
- Когда арендатор помещает запись в систему, дата записи вычисляется на основе их локального DateTime и преобразуется в UTC, сохраненный в базе данных.
Мы также хотим иметь возможность выбирать все вызовы на системном уровне, размещенные между некоторыми датами UTC независимо от арендатора (для общей системной статистики/отчетности)
Наша первоначальная идея
Наша первоначальная идея состояла в том, чтобы сохранить UTC DateTime во всей БД и, конечно же, сохранить смещение часового пояса арендаторов относительно UTC и иметь приложение, которое потребляет БД, всегда преобразует даты в UTC, чтобы сама БД всегда работала с UTC.
Способ 1
Сохранение локальных арендаторов DateTime было бы неплохо для каждого арендатора но тогда у нас есть проблема с такими запросами как:
Выберите * из вызовов WHERE OrderDateTime между UTCDateTime1 и UTCDateTime2
Это проблематично, потому что callDateTime в этом запросе означает другой момент времени, основанный на клиенте. Конечно, этот запрос может включать в себя соединение с таблицей арендаторов, чтобы получить локальное смещение даты и времени, которое затем вычислит callDateTime на лету, чтобы внести коррективы. Это возможно, но не уверен, что это хороший способ сделать это?
Способ 2
С другой стороны, при сохранении UTC DateTime, то когда мы делаем расчет количества звонков, так как день/месяц/год в UTC может отличаться от того, что в локальном DateTime
Возьмем крайний пример: допустим, арендатор опережает UTC на 6 часов, а его локальная дата-время-2017-01-01 02:00. UTC будет 2016-12-31 20:00. Заказ, размещенный в этот момент, должен получить звонки, но если сохранить UTC, то он получит 2016-12-31.
В этом случае в момент создания вызовов в БД мы должны получить UTC datetime, смещение арендаторов и скомпилировать дату вызова на основе пересчитанного локального времени арендаторов, но все равно сохранить столбец DateTime в UTC.
мой вопрос
- Каков предпочтительный способ справиться с подобной ситуацией?
- Есть ли хорошее решение с сохранением времени UTC, потому что это было бы довольно хорошо для нас из-за отчетности на системном уровне?
- Если вы идете с сохранением UTC, является ли метод 2) хорошим способом справиться с этими случаями или есть какой-то лучший/рекомендуемый способ?
- Как запросить звонки в период с 20 августа 2019 года по 30 августа 2019 года? ( Здесь дата всегда арендатор часовой пояс даты )
- Как запросить почасовое количество звонков 20 августа 2019 года ? ( здесь дата всегда дата часового пояса арендатора )
- Как создать ежедневный отчет, основанный на дне часового пояса пользователя?
Что я уже пробовал:
мы используем СПС(хранится закупает) получать данные между двумя датами, но результаты будут не точными.
Richard MacCutchan
Если вы всегда конвертируете метки времени в UTC, то проблем быть не должно. Поэтому, когда пользователь добавляет информацию в базу данных или хочет запросить что-то, содержащее значение времени, просто убедитесь, что оно преобразовано в UTC для базы данных. Это также позволяет арендатору перейти в другой часовой пояс, перейти на летнее время и т. д.
Maciej Los
Звучит как ответ ;)
Richard MacCutchan
Почти, ха-ха.
Maciej Los
Я почти уверен, что нет-почти, но полностью.
Пожалуйста, смотрите мой ответ.
Richard Deeming
NB: Если ваши временные метки могут представлять даты в будущем, убедитесь, что вы знаете о проблемах с их хранением в формате UTC:
Хранение UTC-это не серебряная пуля | блог кодирования Джона Скита[^]