Ответ 1
Если вы используете версию SQL Server, которая знает тип datetimeoffset, этот синтаксис будет работать для получения локального смещения tz сервера:
select datepart(tz,sysdatetimeoffset())
Результат в MINUTES.
У меня есть старая таблица с несколькими строками с столбцом datetime. Я хочу переключить это на datetimeoffset, но я хочу, чтобы иметь возможность передавать данные, которые уже существуют. Поэтому я делаю что-то вроде:
SET IDENTITY_INSERT Table_Temp ON
INSERT INTO Table_Temp
(Col0, ... ColN,)
SELECT
COl0,.... ColN, from
Table_Original;
SET IDENTITY_INSERT Table_Temp OFF
Это работает, но набор смещений равен 0, когда я делаю dattime для назначения datetimeoffset. К счастью, смещение, которое я хочу установить, это смещение текущей системы. Я не гуру tsql, но я не могу понять, как легко это сделать.
Я хочу иметь возможность устанавливать смещение в пределах преобразования. Я собирался прибегнуть к использованию утилиты С# (или PowerShell), но я бы предпочел сохранить ее просто.
Если вы используете версию SQL Server, которая знает тип datetimeoffset, этот синтаксис будет работать для получения локального смещения tz сервера:
select datepart(tz,sysdatetimeoffset())
Результат в MINUTES.
См. ниже для документа, вы, вероятно, хотите что-то вроде:
-- up here set the @time_zone variable.
INSERT INTO Table_Temp
(Col0, ... ColN,)
SELECT
COl0, TODATETIMEOFFSET(COLDATE, @time_zone),.... ColN, from
Table_Original;
От MSDN
Функция SWITCHOFFSET настраивает введите значение DATETIMEOFFSET в указанный часовой пояс, при сохранении значение UTC. Синтаксис SWITCHOFFSET (datetimeoffset_value, часовой пояс). Например, следующее код настраивает текущую систему Значение datetimeoffset для часового пояса GMT +05: 00:
SELECT SWITCHOFFSET (SYSDATETIMEOFFSET(), '-05: 00');
Итак, если текущая система Значение datetimeoffset - 12 февраля, 2009 10: 00: 00.0000000 -08: 00, это код возвращает значение 12 февраля, 2009 13: 00: 00.0000000 -05: 00.
Функция TODATETIMEOFFSET устанавливает смещение временной зоны даты ввода и значение времени. Его синтаксис TODATETIMEOFFSET (date_and_time_value, TIME_ZONE).
Эта функция отличается от SWITCHOFFSET несколькими способами. Первый, это не ограничивается значение datetimeoffset как входное; скорее он принимает любые данные о дате и времени тип. Во-вторых, он не пытается настроить время, основанное на часовом поясе разница между исходным значением и указанный часовой пояс, но вместо этого просто возвращает дату ввода и значение времени с заданным временем zone как значение времени datetimeoffset.
Основная цель Функция TODATETIMEOFSFET - конвертировать типы, которые не являются часовым поясом с учетом DATETIMEOFFSET смещение временной зоны. Если данная дата и значение времени - это DATETIMEOFFSET, изменяется функция TODATETIMEOFSFSET значение DATETIMEOFFSET, основанное на те же оригинальные локальные даты и время значение плюс новый часовой пояс смещение.
Например, текущая система Значение datetimeoffset - 12 февраля, 2009 10: 00: 00.0000000 -08: 00, и вы введите следующий код:
SELECT TODATETIMEOFFSET (SYSDATETIMEOFFSET(), '-05: 00');
Значение 12 февраля 2009 г. Возвращается 10: 00: 00.0000000 -05: 00. Помните, что SWITCHOFFSET функция вернулась 12 февраля 2009 г. 13: 00: 00.0000000 -05: 00, потому что это скорректировано время, основанное на времени зоны между входами (-08: 00) и указанный часовой пояс. (-05: 00)
Как упоминалось ранее, вы можете использовать Функция TODATETIMEOFFSET с любыми даты и времени в качестве входных данных. Для Например, следующий код принимает текущее системное значение даты и времени и возвращает его как значение datetimeoffset с часовым поясом -00: 05:
SELECT TODATETIMEOFSFSET (SYSDATETIME(), '-05: 00');
Эти функции преобразования будут работать некорректно, если сохранение DST в целевом часовом поясе, так как смещение часового пояса изменяется в течение того же года.
Вы можете определить, что смещение текущего SQL-сервера использует следующее.
select datediff(MI,getdate(), getutcdate())
Вам нужно получить смещение за считанные минуты, а не часы, так как есть полчаса и даже четверть часа.
Используя значение минут, вы можете изменить свои значения (при условии, что они были исторически записаны как локальное время), используя что-то вроде
select dateadd(mi,datediff(MI,getdate(), getutcdate()), yourDateField)
Для эффективности я бы вычислил его один раз в переменной и использовал это, поскольку разница не изменится.
Для тех, кто пытается решить эту проблему правильно, учет DST здесь является инструментом для этого.
Это небольшая вариация уже предоставленного ответа и НЕ учитывает изменения DST. Однако это может быть достаточно для многих целей:
dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime)