К сожалению, SQL Server не имеет встроенной функции преобразования часового пояса. Однако это может быть выполнено с помощью SQLCLR. Вы можете создать скалярные пользовательские функции, используя метод DateTime.ToLocalTime().
Да, технически вы можете использовать TimeZoneInfo класс, который имеет такие методы, как ConvertTime(DateTime, TimeZoneInfo, TimeZoneInfo)
и ConvertTimeFromUtc(DateTime, TimeZoneInfo)
, но TimeZoneInfo
класс требует, чтобы сборка имеет PERMISSION_SET
из UNSAFE
тогда DateTime
может работать в качестве SAFE
. Единственным недостатком придерживаться методов DateTime
является то, что они могут конвертировать только между UTC и локальным временем сервера, в отличие от TimeZoneInfo
, который может конвертировать между любыми двумя заданными часовыми поясами.
Поскольку ваши данные уже в GMT/UTC, было бы довольно легко преобразовать в Тихий океан * время использования DateTime.ToLocalTime
, но только если изменить часовой пояс вашего сервера перед тем обновления данных, а не после того, как (как упоминается в вопросе). В этот момент вы могли бы сделать что-то вроде следующего:
ALTER TABLE [SchemaName].[TableName]
ADD [IsConverted] BIT NULL; -- make sure we don't convert multiple times
WHILE (1 = 1)
BEGIN
UPDATE TOP (2000) tab
SET tab.DateField = dbo.ConvertTimeToLocalTime(tab.DateField),
tab.IsConverted = 1
FROM [SchemaName].[TableName] tab
WHERE tab.IsConverted IS NULL;
IF (@@ROWCOUNT = 0)
BEGIN
BREAK;
END;
END;
-- Remove the temporary tracking field, but not until all rows are converted
IF (NOT EXISTS(
SELECT *
FROM [SchemaName].[TableName] tab
WHERE tab.IsConverted IS NULL
)
)
BEGIN
ALTER TABLE [SchemaName].[TableName]
DROP COLUMN [IsConverted];
END;
* Обратите внимание, что я использовал «Pacific» время вместо PST, потому что тихоокеанскому времени может быть или PST или PDT в зависимости от Daylight Savings. Следовательно, попытка преобразования путем простого выполнения DATEADD(HOUR, -7, [DateField])
будет верна для некоторых строк, но не для всех строк.
Кроме того, для тех, кто интересуется данной функцией преобразования, он доступен (хотя и не бесплатно) в полной версии библиотеки SQL# (которой я являюсь автором). Есть несколько сообщений в блогах, которые показывают, как это сделать, хотя я не видел того, что следует за лучшими практиками, так что он будет работать оптимально. Конечно, если это разовое преобразование, то оптимальная производительность по цене, по общему признанию, менее важна, чем менее эффективная, но бесплатная :-).
Я думаю, что решение является скорее решением часового пояса базы данных, но оно не изменяет существующие значения базы данных даты и времени в часовой пояс PST из GMT. – thenextmogul
@thenextmogul В дополнение к тому, что вы сделали о том, что это параметр уровня DB, а не сами данные, это также опция Oracle, опция _not_ SQL Server. –