Подтвердить что ты не робот

Перенос столбца DateTime SQL Server в DateTimeOffset

У меня есть старая таблица с несколькими строками с столбцом 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), но я бы предпочел сохранить ее просто.

4b9b3361

Ответ 1

Если вы используете версию SQL Server, которая знает тип datetimeoffset, этот синтаксис будет работать для получения локального смещения tz сервера:

select datepart(tz,sysdatetimeoffset())

Результат в MINUTES.

Ответ 2

См. ниже для документа, вы, вероятно, хотите что-то вроде:

-- 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');

Ответ 3

Эти функции преобразования будут работать некорректно, если сохранение DST в целевом часовом поясе, так как смещение часового пояса изменяется в течение того же года.

Ответ 4

Вы можете определить, что смещение текущего SQL-сервера использует следующее.

select datediff(MI,getdate(), getutcdate())

Вам нужно получить смещение за считанные минуты, а не часы, так как есть полчаса и даже четверть часа.

Используя значение минут, вы можете изменить свои значения (при условии, что они были исторически записаны как локальное время), используя что-то вроде

select dateadd(mi,datediff(MI,getdate(), getutcdate()), yourDateField)

Для эффективности я бы вычислил его один раз в переменной и использовал это, поскольку разница не изменится.

Ответ 6

Это небольшая вариация уже предоставленного ответа и НЕ учитывает изменения DST. Однако это может быть достаточно для многих целей:

dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime)