Robię kilka zapytań SQL do wyboru i chciałbym przekonwertować moją kolumnę czasu UTC na czas lokalny, aby był wyświetlany jako czas lokalny w moich wynikach zapytania. Uwaga: NIE zamierzam przeprowadzać tej konwersji za pomocą kodu, ale raczej gdy wykonuję ręczne i losowe zapytania SQL względem moich baz danych.
sql
sql-server
Nugs
źródło
źródło
Odpowiedzi:
Możesz to zrobić w następujący sposób na SQL Server 2008 lub nowszym:
Możesz także zrobić mniej szczegółowe:
Cokolwiek robisz, nie używaj
-
do odejmowania dat, ponieważ operacja nie jest atomowa, a czasami otrzymasz nieokreślone wyniki z powodu warunków wyścigu między datetime systemowym a lokalnym datetime sprawdzanym w różnych momentach (tj. Nie-atomowo) .Pamiętaj, że ta odpowiedź nie uwzględnia czasu letniego. Jeśli chcesz dołączyć korektę czasu letniego, zobacz także następujące pytanie SO:
Jak utworzyć funkcję Start and End czasu letniego w programie SQL Server
źródło
Nie znalazłem żadnego z tych przykładów pomocnych w uzyskaniu daty i godziny zapisanej jako UTC do daty i godziny w określonej strefie czasowej (NIE strefy czasowej serwera, ponieważ bazy danych Azure SQL działają jako UTC). Tak sobie z tym poradziłem. Nie jest elegancki, ale jest prosty i daje właściwą odpowiedź bez konieczności utrzymywania innych tabel:
źródło
AT TIME ZONE
składni, należy rozważyć stackoverflow.com/a/44941536/112764 - można łańcuchowe wielu konwersji razem po prostu łącząc kilkaat time zone <blah>
s.dateTimeField AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'
- po prostu łączenie łańcuchówAT TIME ZONE
instrukcji. (@NateJ wspomniał o tym powyżej, widzę teraz)Jeśli podana jest lokalna data
Eastern Standard Time
i chcesz przekonwertować ją z UTC, to w Azure SQL i SQL Server 2016 i nowszych wersjach możesz:Pełną listę nazw stref czasowych można znaleźć w:
I tak, strefy czasowe są źle nazwane - nawet jeśli tak jest
Eastern Standard Time
, uwzględniane są oszczędności światła dziennego.źródło
Jeśli potrzebujesz konwersji innej niż lokalizacja twojego serwera, oto funkcja, która pozwala przekazać standardowe przesunięcie i rozlicza się z US Daylight Savings Times:
źródło
Korzystanie z nowych możliwości programu SQL Server 2016:
Ale procedura CLR działa 5 razy szybciej: „- (
Zwróć uwagę, że przesunięcie dla jednej strefy czasowej może zmienić się na czas zimowy lub letni. Na przykład
wyniki:
Nie można po prostu dodać stałego przesunięcia.
źródło
Jeśli włączanie CLR w bazie danych jest opcją, a także używanie strefy czasowej serwera SQL, można ją dość łatwo zapisać w .Net.
Wchodzi wartość daty i godziny UTC i wychodzi lokalna wartość godziny i czasu względem serwera. Wartości null zwracają wartość null.
źródło
Nie ma prostego sposobu, aby to zrobić we właściwy i ogólny sposób.
Przede wszystkim należy zrozumieć, że przesunięcie zależy od danej daty, strefy czasowej i czasu letniego.
GetDate()-GetUTCDate
daje tylko offset dzisiaj w TZ serwera, co nie ma znaczenia.Widziałem tylko dwa działające rozwiązania i dużo szukałem.
1) Niestandardowa funkcja SQL z kilkoma tabelami danych podstawowych, takimi jak strefy czasowe i reguły DST na TZ. Działa, ale niezbyt elegancko. Nie mogę tego opublikować, ponieważ nie mam kodu.
EDYCJA: Oto przykład tej metody https://gist.github.com/drumsta/16b79cee6bc195cd89c8
2) Dodaj zestaw .net do db, .Net może to zrobić bardzo łatwo. Działa to bardzo dobrze, ale wadą jest to, że musisz skonfigurować kilka parametrów na poziomie serwera, a konfiguracja jest łatwa do złamania, np. Podczas przywracania bazy danych. Używam tej metody, ale nie mogę jej opublikować, ponieważ nie jestem właścicielem kodu.
źródło
Żadne z nich nie działało dla mnie, ale poniżej działało 100%. Mam nadzieję, że pomoże to innym próbować przekonwertować to tak, jak ja.
źródło
declare @StandardOffset int = datediff (hh, GETUTCDATE(), GETDATE())
Oto wersja uwzględniająca czas letni, przesunięcie UTC i nie jest zablokowana na określony rok.
źródło
Odkryłem, że sposób jednorazowy jest zbyt wolny, gdy jest dużo danych. Zrobiłem to, łącząc się z funkcją tabeli, która pozwoliłaby na obliczenie różnicy godzin. Zasadniczo są to segmenty daty i godziny z przesunięciem godziny. Rok będzie 4 rzędy. Więc funkcja stołu
zwróci tę tabelę:
Uwzględnia oszczędności w świetle dziennym. Próbka jego wykorzystania znajduje się poniżej, a pełny post na blogu znajduje się tutaj .
źródło
źródło
Odpowiedź Rona zawiera błąd. Wykorzystuje czas lokalny 2:00 AM, gdy wymagany jest ekwiwalent UTC. Nie mam wystarczającej liczby punktów reputacji, aby skomentować odpowiedź Rona, więc poprawiona wersja pojawia się poniżej:
źródło
Znacznik czasu UNIX to tylko liczba sekund między określoną datą a Epoką Uniksową,
SELECT DATEDIFF (SECOND, {d '1970-01-01'}, GETDATE ()) // To zwróci znacznik czasu UNIX na serwerze SQL
można utworzyć funkcję konwersji lokalnej daty i godziny na Unix UTC za pomocą funkcji przesunięcia kraju na uniksowy znacznik czasu na serwerze SQL
źródło
To proste. Wypróbuj to dla Azure SQL Server:
W przypadku lokalnego serwera SQL:
źródło
Dla użytkowników Azure SQL i
@@Version
> = SQL Server 2016, poniżej jest prosta funkcja przy użyciuAT TIME ZONE
.Aby
@LocalTimeZone
zapoznać się z typami wartości, które można przyjąć, przejdź do tego linku lub Przejdź doKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
źródło
Jako ostrzeżenie - jeśli zamierzasz użyć następujących (zwróć uwagę na milisekundy zamiast minut):
Należy pamiętać, że część DATEDIFF nie zawsze zwraca ten sam numer. Więc nie używaj go do porównywania DateTimes do milisekund.
źródło
Przekonałem się, że ta funkcja jest szybsza niż inne rozwiązania wykorzystujące osobną tabelę lub pętle. To tylko podstawowe stwierdzenie przypadku. Biorąc pod uwagę, że wszystkie miesiące między kwietniem a październikiem mają przesunięcie o 4 godziny (czas wschodni), musimy tylko dodać kilka kolejnych linii przypadków na marginesie dni. W przeciwnym razie przesunięcie wynosi -5 godzin.
Jest to specyficzne dla konwersji z czasu UTC na czas wschodni, ale w razie potrzeby można dodać dodatkowe funkcje strefy czasowej.
źródło
To powinno być w stanie uzyskać czas serwera z DST
sysdatetimeoffset bierze pod uwagę czas letni
źródło
Pierwsza funkcja: skonfigurowana dla włoskiej strefy czasowej (+1, +2), przełącza daty: ostatnia niedziela marca i października, zwraca różnicę między bieżącą strefą czasową i datetime jako parametr.
Kod to:
Następnie funkcja konwertująca datę
źródło
- Uzyskaj czas indyjski standardowy z utc
źródło
Można to zrobić bez funkcji. Poniższy kod przekształci czas UTC w czas górski, uwzględniając oszczędności w ciągu dnia. Dostosuj odpowiednio wszystkie liczby -6 i -7 do swojej strefy czasowej (tj. Dla EST ustawisz odpowiednio na -4 i -5)
źródło
Musisz ponownie sformatować ciąg, a także przekonwertować na właściwy czas. W tym przypadku potrzebowałem czasu Zulu.
źródło
Najlepszy sposób dla Oracle:
Z zakodowaną datetime:
Result:
2018-10-28 00:00
Z nazwami kolumn i tabel:
źródło
Mam kod do wykonania czasu UTC na czas lokalny i czas lokalny na czas UTC, który umożliwia konwersję przy użyciu takiego kodu
i
Funkcje mogą obsługiwać wszystkie lub podzbiory stref czasowych w IANA / TZDB dostarczone przez NodaTime - patrz pełna lista na https://nodatime.org/TimeZones
Pamiętaj, że mój przypadek użycia oznacza, że potrzebuję tylko „bieżącego” okna, umożliwiającego konwersję czasów w przedziale około +/- 5 lat od teraz. Oznacza to, że metoda, której użyłem, prawdopodobnie nie jest dla Ciebie odpowiednia, jeśli potrzebujesz bardzo długiego okresu czasu, ze względu na sposób, w jaki generuje kod dla każdego interwału strefy czasowej w danym zakresie dat.
Projekt jest na GitHub: https://github.com/elliveny/SQLServerTimeConversion
Generuje to kod funkcji SQL zgodnie z tym przykładem
źródło
Cóż, jeśli przechowujesz dane jako datę UTC w bazie danych, możesz zrobić coś tak prostego jak
było to zawsze lokalne od punktu serwera i nie masz problemów z AT
TIME ZONE 'your time zone name'
, jeśli twoja baza danych zostanie przeniesiona do innej strefy czasowej, takiej jak instalacja klienta, strefa czasowa zakodowana na stałe może cię ugryźć.źródło
W Postgresie działa to bardzo ładnie. Powiedz serwerowi czas, w którym czas jest zapisany, „utc”, a następnie poproś go o konwersję do określonej strefy czasowej, w tym przypadku „Brazylia / Wschód”
Uzyskaj pełną listę stref czasowych z poniższym wyborem;
Zobacz szczegóły tutaj.
https://popsql.com/learn-sql/postgresql/how-to-convert-utc-to-local-time-zone-in-postgresql
źródło
Oto prostszy, który uwzględnia dst
źródło
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, GETUTCDATE(), '20150101'), GETDATE())
. Jestem obecnie w CEST (UTC + 2), ale DST nie będzie obowiązywał w Nowy Rok, więc poprawna odpowiedź będzie dla mnie 1 stycznia 2015 01:00. Twoja odpowiedź, podobnie jak odpowiedź zaakceptowana, zwraca 1 stycznia 2015 02:00.