2011-02-10 4 views
27

Я надеюсь преобразовать таблицу, которая имеет поле DATETIMEOFFSET, вплоть до поля DATETIME, но пересчитывает время, обращая внимание на смещение. Это, по сути, преобразует значение в UTC.Как преобразовать Sql Server 2008 DateTimeOffset в DateTime

например.

CreatedOn: 2008-12-19 17:30:09.0000000 +11:00

, которые преобразуются в

CreatedOn: 2008-12-19 06:30:09.0000000

или

CreatedOn: 2008-12-19 06:30:09.0000000 + 00:00 < - это DATETIMEOFFSET, но UTC.

Приветствия :)

ответ

45

Преобразование с использованием практически любого стиля вызовет значение datetime2 быть преобразован в UTC.
Кроме того, переход от datetime2 к DateTimeOffset просто устанавливает смещение на +00:00, за ниже, так что это быстрый способ конвертировать из Datetimeoffset(offset!=0) в Datetimeoffset(+00:00)

declare @createdon datetimeoffset 
set @createdon = '2008-12-19 17:30:09.1234567 +11:00' 

select CONVERT(datetime2, @createdon, 1) 
--Output: 2008-12-19 06:30:09.12 

select convert(datetimeoffset,CONVERT(datetime2, @createdon, 1)) 
--Output: 2008-12-19 06:30:09.1234567 +00:00 
+1

Можно ли объяснить, что означает последний аргумент «1» от CONVERT? Все примеры этого аргумента используют типы символов как выходные или типы ввода. Здесь мы преобразуем datetimeoffset в datetime. –

+0

Функция 'convert()' принимает третий параметр, который определяет формат вывода. [Https://www.w3schools.com/sql/func_convert.asp](https://www.w3schools.com/sql/func_convert.asp). 1 = "mm/dd/yy" format –

+0

Этот третий аргумент действительно не имеет никакого смысла для преобразования из 'datetimeoffset' в' datetime2'. Это для конверсий 'varchar'. https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql (также W3Schools? так много лучших вариантов сейчас!) – brianary

3

Примечание: Информация временная зона отбрасываются в преобразовании, если не указано стиль ("126" здесь). Он также может быть отброшен в некоторых других стилях, я не знаю - в любом случае правильно правильная настройка информации TZ. См. CAST and CONVERT.

select convert(datetime, cast('2008-12-19 17:30:09.0000000 +11:00' as datetimeoffset), 126) as utc; 

Счастливый SQL'ing.

Редактировать

Не уверен, если это имеет значение, но ... datetime фактически не может сохранить этот уровень точности/точности. Если выполнено выше, дробные секунды будут усечены до трех цифр (а точность меньше). То же самое с-datetime2datetimeoffset(7)) производит неусеченной значение:

select convert(datetime2, cast('2008-12-19 17:30:09.1234567 +11:00' as datetimeoffset(7)), 126) as utc; 
+0

Что такое стиль 126? и почему 126? –

+0

@ Pure.Krome В ответ ответьте на CAST и CONVERT. 126, потому что мне нравится ISO 8601 и нужно было выбрать один. Это действительно ничем не отличается от выбора кибервики 1. Как отмечено (в обоих ответах) некоторые стили * могут * не учитывать TZ. –

+1

Быстрый тест в SQL Server 2008 R2 показывает, что только с использованием стиля '0' или (эквивалентно), опускающего код стиля, отбрасывают информацию о часовом поясе. Любой из других кодов, перечисленных в документе MSDN, сохранит его. –

17

Я хотел бы использовать встроенный вариант SQL:

select SWITCHOFFSET(cast('2008-12-19 17:30:09.0000000 +11:00' as datetimeoffset),'+00:00') 
9

Я знаю, что это старый вопрос, но если вы хотите преобразовать DateTimeOffset в DateTime, я думаю, вам нужно учитывать часовой пояс сервера, на котором вы конвертируете. Если вы просто выполняете CONVERT (datetime, @MyDate, 1), вы просто потеряете часовой пояс, что, вероятно, приведет к неправильному преобразованию.

Я думаю, вам сначала нужно переключить смещение значения DateTimeOffset, а затем выполнить преобразование.

DECLARE @MyDate DATETIMEOFFSET = '2013-11-21 00:00:00.0000000 -00:00'; 
SELECT CONVERT(DATETIME, SWITCHOFFSET(@MyDate, DATEPART(tz,SYSDATETIMEOFFSET()))); 

Результат преобразования '2013-11-21 00: 00: 00,0000000 -00: 00' к DateTime на сервере, который является смещение -7: 00 будет 2013-11-20 17:00 : 00,000. В соответствии с вышеприведенной логикой, это не соответствует часовому поясу сервера или смещению значения DateTime, оно будет преобразовано в DateTime в часовой пояс серверов.

Я считаю, что вам нужно сделать это, потому что значение DateTime включает в себя предположение, что это значение находится в часовом поясе сервера.

+0

Спасибо за это - мы были запустив в Azure больше кода, но запрашивая локальные базы данных, приятно иметь DateTimeOffset в облаке, обычно это UTC, а затем преобразовывать его в локальное время, не зная часовой пояс локального сервера. Использование DateTimeOffeset в облаке также изолирует нас, если облако - это не UTC. –

Смежные вопросы