Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Преобразуване на дата и час от часова зона в часова зона в sql сървър

Времевите клейма на Unix са цял брой секунди от 1 януари 1970 г. UTC.

Ако приемем, че имате предвид, че имате цяла колона във вашата база данни с това число, тогава часовата зона на вашия сървър на база данни е без значение.

Първо преобразувайте клеймото за време в datetime тип:

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

Това ще бъде UTC datetime който съответства на вашето времево клеймо.

След това трябва да знаете как да коригирате тази стойност към вашата целева часова зона. В голяма част от света една зона може да има множество отмествания поради лятното часово време.

За съжаление, SQL Server няма възможност да работи директно с работни часови зони. Така че, ако използвате например тихоокеанското време в САЩ, няма как да знаете дали трябва да извадите 7 часа или 8 часа. Други бази данни (Oracle, Postgres, MySql и т.н.) имат вградени начини да се справят с това, но уви, SQL Server не го прави. Така че, ако търсите решение с общо предназначение, ще трябва да направите едно от следните:

  • Импортирайте данни за часовата зона в таблица и поддържайте тази таблица при промяна на правилата за часовата зона. Използвайте тази таблица с куп персонализирана логика, за да разрешите отместването за определена дата.

  • Използвайте xp_regread за да стигнете до ключовете на системния регистър на Windows, които съдържат данни за часовата зона, и отново да използвате куп персонализирана логика, за да разрешите отместването за определена дата. Разбира се, xp_regread е лошо нещо, изисква определени разрешения и не се поддържа или документира.

  • Напишете SQLCLR функция, която използва TimeZoneInfo клас в .Net. За съжаление, този изисква "опасен" SQLCLR асембли и може да причини лоши неща.

IMHO, нито един от тези подходи не е много добър и няма добро решение това да се направи директно в SQL. Най-доброто решение би било да върнете UTC стойността (или оригиналното цяло число, или datetime в UTC) към кода на вашето приложение за повикване и вместо това направете преобразуването на часовата зона там (с, например, TimeZoneInfo в .Net или подобни механизми в други платформи).

ОБАЧЕ - извадихте късмет, че Кувейт е (и винаги е бил) в зона, която не преминава към лятно часово време. Винаги е било UTC+03:00. Така че можете просто да добавите три часа и да върнете резултата:

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

Но имайте предвид, че това не е решение с общо предназначение, което ще работи във всяка часова зона.

Ако желаете, можете да върнете един от другите типове SQL данни, като например datetimeoffset , но това само ще ви помогне да отразите, че стойността е компенсирана за три часа спрямо всеки, който може да я погледне. Това няма да направи процеса на преобразуване по-различен или по-добър.

Актуализиран отговор

Създадох проект за поддръжка на часови зони в SQL Server. Можете да го инсталирате от тук . След това можете просто да конвертирате така:

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

Можете да използвате всяка часова зона от базата данни tz на IANA , включително тези, които използват лятно часово време.

Все още можете да използвате метода, който показах по-горе, за да конвертирате от unix timestamp. Като ги съберем заедно:

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

Актуализиран отново

С SQL Server 2016 вече има вградена поддръжка за часови зони с AT TIME ZONE изявление. Това също е налично в Azure SQL база данни (v12).

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

Още примери в това съобщение.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server Agent - SSIS пакет - Грешка 0x80131904 - Времето за изчакване е изтекло

  2. Външни ключове на SQL Server през границите на базата данни - техники за налагане

  3. Заявката работи бавно с израз за дата, но бързо с низов литерал

  4. В SQL Server как да генерирам ИД на първичен ключ с автоматично нарастване, който се състои от година, специален знак и номер на последователна серия?

  5. Salesforce SOQL от SQL Server