sql >> Database teknologi >  >> RDS >> Sqlserver

Dato tid konvertering fra tidszone til tidszone i sql server

Unix-tidsstempler er heltal antal sekunder siden 1. januar 1970 UTC.

Hvis du antager, at du har en heltalskolonne i din database med dette tal, så er tidszonen for din databaseserver irrelevant.

Konverter først tidsstemplet til en datetime type:

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

Dette vil være UTC datetime der svarer til dit tidsstempel.

Så skal du vide, hvordan du justerer denne værdi til din måltidszone. I store dele af verden kan en enkelt zone have flere forskydninger på grund af sommertid.

Desværre har SQL Server ingen mulighed for at arbejde med arbejdstidszoner direkte. Så hvis du for eksempel brugte amerikansk stillehavstid, ville du ikke have nogen mulighed for at vide, om du skulle trække 7 timer eller 8 timer fra. Andre databaser (Oracle, Postgres, MySql osv.) har indbyggede måder at håndtere dette på, men desværre gør SQL Server ikke. Så hvis du leder efter en generel løsning, skal du gøre et af følgende:

  • Importer tidszonedata til en tabel, og bevar denne tabel, efterhånden som tidszonereglerne ændres. Brug den tabel med en masse tilpasset logik til at løse forskydningen for en bestemt dato.

  • Brug xp_regread for at komme til Windows registreringsdatabasenøglerne, der indeholder tidszonedata, og igen bruge en masse tilpasset logik til at løse forskydningen for en bestemt dato. Selvfølgelig, xp_regread er en dårlig ting at gøre, kræver visse tilladelser, og er ikke understøttet eller dokumenteret.

  • Skriv en SQLCLR-funktion, der bruger TimeZoneInfo klasse i .Net. Desværre kræver denne en "usikker" SQLCLR-assembly , og kan få dårlige ting til at ske.

IMHO, ingen af ​​disse tilgange er særlig gode, og der er ingen god løsning til at gøre dette direkte i SQL. Den bedste løsning ville være at returnere UTC-værdien (enten det oprindelige heltal eller datetime ved UTC) til din opkaldende applikationskode, og foretag tidszonekonverteringen der i stedet (med f.eks. TimeZoneInfo i .Net eller lignende mekanismer i andre platforme).

DOG - du har været heldig, at Kuwait er (og altid har været) i en zone, der ikke ændrer sig for sommertid. Det har altid været UTC+03:00. Så du kan blot tilføje tre timer og returnere resultatet:

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

Men anerkend, at dette ikke er en generel løsning, der fungerer i enhver tidszone.

Hvis du ville, kunne du returnere en af ​​de andre SQL-datatyper, såsom datetimeoffset , men dette vil kun hjælpe dig med at afspejle, at værdien er tre timers forskudt til den, der måtte se på den. Det vil ikke gøre konverteringsprocessen anderledes eller bedre.

Opdateret svar

Jeg har lavet et projekt til at understøtte tidszoner i SQL Server. Du kan installere det herfra . Så kan du blot konvertere sådan:

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

Du kan bruge en hvilken som helst tidszone fra IANA tz-databasen , inklusive dem, der bruger sommertid.

Du kan stadig bruge metoden, jeg viste ovenfor, til at konvertere fra et unix-tidsstempel. Sætter dem begge sammen:

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

Opdateret igen

Med SQL Server 2016 er der nu indbygget understøttelse af tidszoner med AT TIME ZONE udmelding. Dette er også tilgængeligt i Azure SQL Database (v12).

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

Flere eksempler i denne meddelelse.




  1. DB-migrering med NextForm Multi-Table Wizard

  2. SQL ROWNUM hvordan man returnerer rækker mellem et specifikt område

  3. SÆT FMTONLY TIL i Oracle-forespørgsler

  4. Sådan konverteres tid til dato i den lokale tidszone under forespørgsel