Мой локальный сервер разработки находится на Ближнем Востоке, но мой рабочий сервер находится в Великобритании.
Мне нужно показать дату пользователю в его часовом поясе. Например, если пользователь находится в Саудовской Аравии, мне нужно показать время в соответствии с форматом Саудовской Аравии.
Должен ли я создать новую таблицу базы данных с именем TimeZone и сохранить время в формате UTC?
sql-server
sql-server-2008
timezone
user960567
источник
источник
Ответы:
К сожалению, нет быстрого решения этой проблемы. Интернационализация приложения должна быть частью самых первых обсуждений дизайна, поскольку она действительно затрагивает множество различных областей, включая сравнение даты / времени и выходное форматирование.
В любом случае, чтобы начать делать все правильно, важно хранить информацию о часовом поясе со временем . Другими словами, осознание того, что дата / время не
20130407 14:50
имеют смысла без (а) включения текущего смещения UTC для часового пояса (примечание 1) или (b) обеспечения того, что вся логика, вставляющая эти значения, сначала преобразуется в определенное фиксированное смещение ( скорее всего 0). Без этих двух данных значения времени несопоставимы , а данные повреждены . ( Кстати, последний метод - игра с огнем (примечание 2) ; не делайте этого.)В SQL Server 2008+ вы можете сохранять смещение со временем напрямую, используя
datetimeoffset
тип данных. (Для полноты, в 2005 году и ранее, я бы добавил второй столбец для хранения текущего значения смещения UTC (в минутах).)Это облегчает работу приложений настольного типа, поскольку на этих платформах обычно есть механизмы для автоматического преобразования даты / времени + часового пояса в местное время и последующего форматирования для вывода, все на основе региональных настроек пользователя.
Для сети, которая по своей природе является автономной архитектурой, даже с правильно настроенными внутренними данными, она более сложна, потому что вам нужна информация о клиенте, чтобы иметь возможность выполнять преобразование и / или форматирование. Обычно это делается с помощью настроек пользовательских настроек (приложение конвертирует / форматирует вещи перед выводом) или просто показывает вещи с одинаковым фиксированным форматом и смещением часового пояса для всех (что в настоящее время делает платформа Stack Exchange).
Вы можете видеть, как, если внутренние данные не настроены должным образом, очень быстро они станут сложными и хакерскими. Я не рекомендовал бы идти по любому из этих путей, потому что у вас просто будет больше проблем в будущем.
Примечание 1:
Смещение UTC часового пояса не является фиксированным: рассмотрите переход на летнее время, когда смещение UTC зоны изменяется на плюс или минус час. Кроме того, даты перехода на летнее время в зонах регулярно меняются. Таким образом, использование
datetimeoffset
(или совокупностьlocal time
иUTC offset at that time
) приводит к максимальному восстановлению информации.Заметка 2:
Речь идет об управлении вводом данных. Хотя нет надежного способа проверки входящих значений, лучше применять простой стандарт, который не требует вычислений. Если общедоступный API ожидает тип данных, который включает смещение, это требование будет ясно для вызывающей стороны.
Если это не так, вызывающая сторона должна полагаться на документацию (если они ее читают), или вычисления выполняются неправильно и т. Д. При смещении требуется меньше режимов сбоя / ошибки, в частности для распределенной системы ( или даже просто веб / база данных на отдельных серверах, как здесь).
Хранение смещения в любом случае убивает двух зайцев одним выстрелом; и даже если это не требуется сейчас , это делает возможность доступной позже при необходимости. Правда, это требует больше памяти, но я думаю, что это стоит компромисса, потому что данные будут потеряны, если они никогда не будут записаны в первую очередь.
источник
datetimeoffset
означает «это локальное время пользователя / компьютера, когда это произошло» - нам не нужно знать, действовал ли DST или нет, потому что заданное смещение UTC всегда присутствует (встроено вdatetimeoffset
значение).Я разработал комплексное решение для преобразования часовых поясов в SQL Server. См. Поддержка часовых поясов SQL Server на GitHub .
Он правильно обрабатывает преобразования между часовыми поясами и в UTC, включая переход на летнее время.
По своей концепции он аналогичен решению «T-SQL Toolbox», описанному в ответе adss, но использует более распространенные часовые пояса IANA / Olson / TZDB вместо Microsoft и включает в себя утилиты для хранения данных в новых выпусках TZDB выходи.
Пример использования (для ответа на ОП):
Смотрите readme на GitHub для дополнительных API и подробного объяснения.
Также обратите внимание, что, поскольку это решение на основе UDF, оно не предназначено для производительности в качестве основной цели. Было бы еще лучше, если бы эта функциональность была встроена в SQL Server, подобно тому, как эта
CONVERT_TZ
функция существует в Oracle и MySQL.источник
SQL Server внес изменения в 2005 году, когда внутренний часовой пояс сохраняется в UTC. Во многом это было связано с гео-репликацией и проекторами высокой доступности, включающими доставку журналов, а сохранение времени доставки журналов в разных часовых поясах сделало невозможным их восстановление старым методом.
Таким образом, сохранение всего внутри UTC времени позволило SQL Server хорошо работать в глобальном масштабе. Это одна из причин, по которой переход на летнее время является проблемой для Windows, поскольку другие продукты MS, такие как Outlook, также сохраняют дату / время внутри системы в формате UTC и создают смещение, которое необходимо исправить.
Я работаю в компании, где у нас есть тысячи серверов (хотя не MS SQL Server, но все виды серверов), разбросанных по всему миру, и если бы мы не специально заставляли все работать по UTC, мы бы сошли с ума очень быстро.
источник
Я разработал и опубликовал проект «T-SQL Toolbox» для codeplex, чтобы помочь всем, кто борется с обработкой даты и времени в SQL Server. Это открытый исходный код и полностью бесплатное использование.
Он предлагает простые функции преобразования даты и времени с использованием простого T-SQL с дополнительными таблицами конфигурации из коробки.
В вашем примере вы можете использовать следующий пример:
Это вернет преобразованное значение даты и времени для вашего пользователя.
Список всех поддерживаемых часовых поясов можно найти в таблице «DateTimeUtil.Timezone», также предоставленной в базе данных T-SQL Toolbox.
источник
Возможно, я упускаю что-то очевидное, но если все, что вам нужно, это отображать дату в формате пользовательского часового пояса и языка, самый простой способ - всегда сохранять даты в формате UTC в базе данных и позволить клиентскому приложению преобразовывать UTC в локальный часовой пояс и используйте региональные настройки пользователя для форматирования даты соответственно.
источник