Obecnie używam następujących danych, aby uzyskać lokalną datę / godzinę z godziny UTC:
SET @offset = DateDiff(minute, GetUTCDate(), GetDate())
SET @localDateTime = DateAdd(minute, @offset, @utcDateTime)
Mój problem polega na tym, że jeśli czas letni pojawia się między GetUTCDate()
a @utcDateTime
, @localDateTime
kończy się godzina przerwy.
Czy istnieje prosty sposób na konwersję z utc na czas lokalny dla daty, która nie jest bieżącą datą?
Używam SQL Server 2005
WITH PERMISSION_SET = UNSAFE
. Niektóre środowiska nie pozwalają na to, tak jak AWS RDS. I to jest niebezpieczne. Niestety nie ma pełnej implementacji strefy czasowej .Net, którą można wykorzystać bezunsafe
pozwolenia. Zobacz tutaj i tutaj .Opracowałem i opublikowałem projekt T-SQL Toolbox na codeplex, aby pomóc każdemu, kto zmaga się z obsługą czasu i strefy czasowej w Microsoft SQL Server. Jest open source i całkowicie darmowy.
Oferuje łatwe UDF do konwersji danych za pomocą zwykłego T-SQL (bez CLR) oraz wstępnie wypełnione tabele konfiguracji po wyjęciu z pudełka. I ma pełną obsługę DST (czasu letniego).
Lista wszystkich obsługiwanych stref czasowych znajduje się w tabeli „DateTimeUtil.Timezone” (podanej w bazie danych T-SQL Toolbox).
W twoim przykładzie możesz użyć następującej próbki:
Zwróci to skonwertowaną wartość lokalnej daty i godziny.
Niestety jest obsługiwany w SQL Server 2008 lub nowszym tylko z powodu nowszych typów danych (DATE, TIME, DATETIME2). Ponieważ jednak podano pełny kod źródłowy, możesz łatwo dostosować tabele i UDF, zastępując je DATETIME. Nie mam MSSQL 2005 dostępnego do testowania, ale powinien on również działać z MSSQL 2005. W przypadku pytań daj mi znać.
źródło
Zawsze używam tego polecenia TSQL.
To jest bardzo proste i działa.
źródło
Znalazłem tę odpowiedź na StackOverflow, która udostępnia funkcję zdefiniowaną przez użytkownika, która wydaje się dokładnie tłumaczyć czasy danych
Jedyną rzeczą, którą musisz zmodyfikować, jest
@offset
zmienna u góry, aby ustawić przesunięcie strefy czasowej serwera SQL, na którym działa ta funkcja. W moim przypadku nasz serwer SQL używa EST, czyli GMT - 5To nie jest idealne i prawdopodobnie nie zadziała w wielu przypadkach, np. Ma półgodzinne lub 15-minutowe przesunięcia TZ (dla tych poleciłbym funkcję CLR jak Kevin ), jednak działa wystarczająco dobrze w większości ogólnych stref czasowych na północy Ameryka.
źródło
W przypadku SQL Server 2016+ można użyć AT TIME ZONE . Będzie on automatycznie obsłużyć cały dzień światło razy oszczędności.
źródło
Istnieje kilka dobrych odpowiedzi na podobne pytanie dotyczące przepełnienia stosu. Skończyło się na użyciu T-SQL z drugiej odpowiedzi Boba Albrighta, aby posprzątać bałagan spowodowany przez konsultanta konwersji danych.
Działało ono dla prawie wszystkich naszych danych, ale później zdałem sobie sprawę, że jego algorytm działa tylko w przypadku dat sięgających 5 kwietnia 1987 r. , A my mieliśmy pewne daty z lat 40. XX wieku, które nadal nie zostały poprawnie przekonwertowane. Ostatecznie potrzebowaliśmy
UTC
dat w naszej bazie danych SQL Server, aby dopasować się do algorytmu w programie innej firmy, który używał interfejsu API Java do konwersji zUTC
czasu lokalnego.Podoba mi się
CLR
przykład w powyższej odpowiedzi Kevina Feasela z wykorzystaniem przykładu Harsha Chawli , a także chciałbym porównać go z rozwiązaniem wykorzystującym Javę, ponieważ nasz interfejs używa Javy doUTC
konwersji na czas lokalny.Wikipedia wspomina o 8 różnych poprawkach do konstytucji, które wymagają dostosowania stref czasowych przed 1987 r., A wiele z nich jest bardzo zlokalizowanych w różnych stanach, więc istnieje szansa, że CLR i Java mogą je interpretować inaczej. Czy Twój kod aplikacji frontonu używa dotnet lub Java, czy też daty przed 1987 r. Stanowią dla ciebie problem?
źródło
Możesz to łatwo zrobić za pomocą procedury przechowywanej CLR.
Dostępne strefy czasowe możesz przechowywać w tabeli:
Ta procedura składowana wypełni tabelę możliwymi strefami czasowymi na twoim serwerze.
źródło
WITH PERMISSION_SET = UNSAFE
. Niektóre środowiska nie pozwalają na to, tak jak AWS RDS. I to jest niebezpieczne. Niestety nie ma pełnej implementacji strefy czasowej .Net, którą można wykorzystać bezunsafe
pozwolenia. Zobacz tutaj i tutaj .Wersja SQL Server 2016 rozwiąże ten problem raz na zawsze . We wcześniejszych wersjach rozwiązanie CLR jest prawdopodobnie najłatwiejsze. Lub dla określonej reguły DST (jak tylko USA), funkcja T-SQL może być stosunkowo prosta.
Myślę jednak, że ogólne rozwiązanie T-SQL może być możliwe. Tak długo, jak
xp_regread
działa, spróbuj tego:(Złożona) funkcja T-SQL mogłaby użyć tych danych do ustalenia dokładnego przesunięcia dla wszystkich dat podczas bieżącej reguły DST.
źródło
źródło
Oto odpowiedź napisana dla konkretnej aplikacji w Wielkiej Brytanii i oparta wyłącznie na SELECT.
Nie dotyczy między północą a 1 nad ranem w dniu rozpoczęcia dnia. Można to poprawić, ale aplikacja, dla której została napisana, nie wymaga tego.
źródło