Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Konwersja daty i godziny ze strefy czasowej na strefę czasową w serwerze sql

Uniksowe znaczniki czasu to całkowita liczba sekund od 1 stycznia 1970 UTC.

Zakładając, że masz na myśli, że masz w bazie danych kolumnę liczb całkowitych o tym numerze, strefa czasowa serwera bazy danych jest nieistotna.

Najpierw przekonwertuj znacznik czasu na datetime typ:

SELECT DATEADD(second, yourTimeStamp, '1970-01-01')

To będzie czas UTC datetime który odpowiada Twojej sygnaturze czasowej.

Następnie musisz wiedzieć, jak dostosować tę wartość do docelowej strefy czasowej. W dużej części świata pojedyncza strefa może mieć wiele przesunięć ze względu na czas letni.

Niestety SQL Server nie ma możliwości bezpośredniej pracy w strefach czasowych. Jeśli więc używałbyś na przykład czasu pacyficznego, nie miałbyś możliwości sprawdzenia, czy należy odjąć 7 godzin, czy 8 godzin. Inne bazy danych (Oracle, Postgres, MySql itp.) mają wbudowane sposoby obsługi tego, ale niestety SQL Server nie. Jeśli więc szukasz rozwiązania ogólnego przeznaczenia, musisz wykonać jedną z następujących czynności:

  • Importuj dane stref czasowych do tabeli i utrzymuj tę tabelę w miarę zmiany reguł dotyczących stref czasowych. Użyj tej tabeli z mnóstwem niestandardowej logiki, aby rozwiązać przesunięcie dla określonej daty.

  • Użyj xp_regread aby uzyskać dostęp do kluczy rejestru systemu Windows, które zawierają dane strefy czasowej, i ponownie użyć kilku niestandardowej logiki, aby rozwiązać przesunięcie dla określonej daty. Oczywiście xp_regread jest złą rzeczą, wymaga przyznania pewnych uprawnień i nie jest obsługiwana ani dokumentowana.

  • Napisz funkcję SQLCLR, która używa TimeZoneInfo klasa w .Net. Niestety, ten wymaga „niebezpiecznego” zestawu SQLCLR i może spowodować złe rzeczy.

IMHO, żadne z tych podejść nie jest bardzo dobre i nie ma dobrego rozwiązania, aby zrobić to bezpośrednio w SQL. Najlepszym rozwiązaniem byłoby zwrócenie wartości UTC (albo oryginalnej liczby całkowitej, albo datetime w UTC) do kodu aplikacji wywołującej i zamiast tego wykonaj konwersję strefy czasowej (na przykład za pomocą TimeZoneInfo w .Net lub podobnych mechanizmach na innych platformach).

JEDNAK - masz szczęście, że Kuwejt jest (i zawsze był) w strefie, która nie zmienia się na czas letni. Zawsze było UTC+03:00. Możesz więc po prostu dodać trzy godziny i zwrócić wynik:

SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01'))

Pamiętaj jednak, że nie jest to rozwiązanie ogólnego przeznaczenia, które będzie działać w dowolnej strefie czasowej.

Jeśli chcesz, możesz zwrócić jeden z pozostałych typów danych SQL, taki jak datetimeoffset , ale pomoże to tylko zauważyć, że wartość jest przesunięta o trzy godziny dla każdego, kto może na nią spojrzeć. Nie zmieni to procesu konwersji ani nie zmieni go.

Zaktualizowana odpowiedź

Stworzyłem projekt do obsługi stref czasowych w SQL Server. Możesz go zainstalować tutaj . Następnie możesz po prostu przekonwertować w ten sposób:

SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait')

Możesz użyć dowolnej strefy czasowej z bazy danych IANA tz , w tym te, które korzystają z czasu letniego.

Nadal możesz użyć metody, którą pokazałem powyżej, aby przekonwertować ze znacznika czasu uniksowego. Łącząc je razem:

SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait')

Ponowna aktualizacja

W SQL Server 2016 jest teraz wbudowana obsługa stref czasowych z AT TIME ZONE oświadczenie. Jest to również dostępne w Azure SQL Database (v12).

SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time'

Więcej przykładów w tym ogłoszeniu.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak TRY_CAST() działa w SQL Server

  2. Instalowanie Microsoft SQL Server 2012 Enterprise Edition z dodatkiem Service Pack 1

  3. Połączenie krzyżowe bez zduplikowanych kombinacji

  4. Nagłówki kolumn T-SQL Pivot/Unpivot(Transpose) potrzebne jako wiersze danych

  5. SQL — przestaw wiele kolumn bez agregatów