Перенос столбца DateTime SQL Server в DateTimeOffset - PullRequest
22 голосов
/ 05 января 2010

У меня есть старая таблица с несколькими строками, в которой есть столбец 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, когда я делаю назначение времени от даты до даты и времени. К счастью, смещение, которое я хочу установить, является смещением текущей системы. Я не гуру Tsql, но я не могу найти легкий способ сделать это.

Я хочу иметь возможность установить смещение в конвертации. Я собирался прибегнуть к использованию утилиты c # (или PowerShell), но я бы предпочел, чтобы она была простой.

Ответы [ 6 ]

22 голосов
/ 05 января 2010

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

-- 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:

ВЫБРАТЬ 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 в качестве ввода; скорее он принимает любые данные даты и времени тип. Во-вторых, он не пытается настроить время на основе часового пояса разница между исходным значением и указанный часовой пояс, но вместо этого просто возвращает введенную дату и значение времени с указанным временем зона в качестве значения datetimeoffset.

Основное назначение Функция TODATETIMEOFFSET предназначена для конвертировать типы, которые не являются часовым поясом в курсе DATETIMEOFFSET по данным смещение часового пояса. Если данная дата и значение времени является DATETIMEOFFSET, изменяется функция TODATETIMEOFFSET значение DATETIMEOFFSET, основанное на та же оригинальная местная дата и время значение плюс новый данный часовой пояс смещение.

Например, текущая система значение datetimeoffset - 12 февраля, 2009 10: 00: 00.0000000 -08: 00, и вы запустите следующий код:

ВЫБРАТЬ 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:

ВЫБРАТЬ TODATETIMEOFFSET (SYSDATETIME (), '-05: 00');

4 голосов
/ 15 декабря 2010

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

4 голосов
/ 11 октября 2010

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

select datepart(tz,sysdatetimeoffset())

Результат в МИНУТАХ.

2 голосов
/ 05 января 2010

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

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

Вам необходимо получить смещение в минутах, а не часах, так как есть полчаса и дажечасовой пояс четверти часа.

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

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

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

1 голос
/ 09 сентября 2016

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

dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime)
1 голос
/ 18 июня 2016

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

https://github.com/mj1856/SqlServerTimeZoneSupport

...