2011-02-10 9 views
27

Mam nadzieję, że przekształcenie tabeli, która ma pole DATETIMEOFFSET, w dół do pola DATETIME BUT przelicza czas, zwracając uwagę na przesunięcie. W efekcie konwertuje wartość na UTC.Jak przekonwertować SQL Server 2008 DateTimeOffset na DateTime

np.

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

że będzie zamieniony na

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

lub

CreatedOn: 2008-12-19 06:30:09.0000000 + 00:00 < - to jest DATETIMEOFFSET, ale UTC.

Cheers :)

Odpowiedz

45

Konwersja za pomocą niemal każdego stylu spowoduje, że wartość datetime2 być przekonwertowany do UTC.
Ponadto, konwersja z datetime2 do datetimeoffset prostu ustawia przesunięcie w +00:00, za poniżej, więc jest to szybki sposób przekonwertować z Datetimeoffset(offset!=0) do 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

Czy można wyjaśnić, co znaczy ostatni argument "1" CONVERT? Wszystkie przykłady tego argumentu używają typów znaków jako typu wyjściowego lub wejściowego. Tutaj konwertujemy datetimeoffset na datetime. –

+0

Funkcja 'convert()' pobiera trzeci parametr określający format wyjścia. [https://www.w3schools.com/sql/func_convert.asp](https://www.w3schools.com/sql/func_convert.asp). 1 = "mm/dd/rr" format –

+0

Trzeci argument nie ma żadnego sensu dla konwersji z 'datetimeoffset' na' datetime2'. Dotyczy konwersji "varchar'. https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql (również W3Schools? tak wiele lepszych opcji teraz!) – brianary

3

Uwaga: informacja czasowa jest wyrzucić nawrócenia jeśli nie styl ("126" tutaj) jest określona. Może być również odrzucony w niektórych innych stylach, nie wiem - w każdym razie poniższe poprawnie dostosowuje się do informacji TZ. Zobacz CAST and CONVERT.

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

Happy SQLing.

Edit

Nie wiem, czy to ważne, ale ... datetime Nie można właściwie przechowywać ten poziom dokładności/precyzji. Jeśli powyższe zostanie uruchomione, ułamkowe sekundy zostaną obcięte do 3 cyfr (a dokładność jest mniejsza niż). To samo-samo datetime2 (i datetimeoffset(7)) produkuje non-obcięte wartość:

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

co to jest styl 126? i dlaczego 126? –

+0

@ Pure.Krome Zobacz link do CAST i CONVERT w odpowiedzi. 126 ponieważ lubię ISO 8601 i musiałem wybrać jeden. To naprawdę nie różni się od wybierania cyberwiki 1. Jak zauważono (w obu odpowiedziach) pewne style * mogą * nie uwzględniać TZ. –

+1

Szybki test w SQL Server 2008 R2 pokazuje, że tylko używając stylu '0' lub (równoważnie) pomijając kod stylu, odrzuć informacje o strefie czasowej. Każdy z pozostałych kodów wymienionych w dokumencie MSDN zachowa go. –

17

będę korzystać z wbudowanych opcji SQL:

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

wiem, jest to stara sprawa, ale jeśli chcesz przekonwertować datetimeoffset do DateTime, myślę, że trzeba wziąć pod uwagę strefę czasową serwera jesteś konwersji na. Jeśli po prostu wykonasz CONVERT (datetime, @MyDate, 1), stracisz strefę czasową, co prawdopodobnie spowoduje błędną konwersję.

Myślę, że najpierw trzeba przełączyć przesunięcie wartości DateTimeOffset, a następnie wykonaj konwersję.

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

Wynik konwersji '2013-11-21 00: 00: +00,0000000 -00: 00' do DateTime na serwerze, który jest offsetowej -7: 00 będzie 2013-11-20 17:00 : 00.000. Z powyższą logiką nie ma znaczenia strefa czasowa serwera lub przesunięcie wartości DateTime, zostanie ona przekonwertowana na DateTime w strefie czasowej serwera.

Uważam, że należy to zrobić, ponieważ wartość DateTime zawiera założenie, że wartość znajduje się w strefie czasowej serwera.

+0

Dzięki za to - byliśmy o wiele więcej kodu na Azure, ale wysyłając zapytania do lokalnych baz danych, miło jest móc wziąć DateTimeOffset w chmurze, zwykle jest to UTC, a następnie przekonwertować go na czas lokalny bez konieczności znajomości strefy czasowej lokalnego serwera. Używanie DateTimeOffeset w chmurze również izoluje nas, jeśli chmura nie jest UTC. –

Powiązane problemy