Unix-tijdstempels zijn een geheel aantal seconden sinds 1 januari 1970 UTC.
Ervan uitgaande dat je bedoelt dat je een integer-kolom in je database hebt met dit nummer, dan is de tijdzone van je databaseserver niet relevant.
Converteer eerst de tijdstempel naar een datetime
typ:
SELECT DATEADD(second, yourTimeStamp, '1970-01-01')
Dit wordt de UTC datetime
die overeenkomt met uw tijdstempel.
Dan moet u weten hoe u deze waarde kunt aanpassen aan uw doeltijdzone. In een groot deel van de wereld kan een enkele zone meerdere offsets hebben vanwege de zomertijd.
Helaas heeft SQL Server geen mogelijkheid om rechtstreeks met werktijdzones te werken. Dus als u bijvoorbeeld US Pacific-tijd zou gebruiken, zou u niet weten of u 7 uur of 8 uur moet aftrekken. Andere databases (Oracle, Postgres, MySql, etc.) hebben ingebouwde manieren om hiermee om te gaan, maar helaas, SQL Server niet. Dus als u op zoek bent naar een oplossing voor algemeen gebruik, moet u een van de volgende dingen doen:
-
Importeer tijdzonegegevens in een tabel en onderhoud die tabel als de tijdzoneregels veranderen. Gebruik die tabel met een heleboel aangepaste logica om de offset voor een bepaalde datum op te lossen.
-
Gebruik
xp_regread
om bij de Windows-registersleutels te komen die tijdzonegegevens bevatten, en opnieuw een heleboel aangepaste logica te gebruiken om de offset voor een bepaalde datum op te lossen. Natuurlijk,xp_regread
is een slechte zaak om te doen, vereist bepaalde verleende machtigingen en wordt niet ondersteund of gedocumenteerd. -
Schrijf een SQLCLR-functie die gebruikmaakt van de
TimeZoneInfo
klasse in .Net. Helaas vereist deze een "onveilige" SQLCLR-assembly , en kan leiden tot slechte dingen.
IMHO, geen van deze benaderingen is erg goed, en er is geen goede oplossing om dit rechtstreeks in SQL te doen. De beste oplossing zou zijn om de UTC-waarde te retourneren (ofwel het oorspronkelijke gehele getal, of de datetime
bij UTC) naar uw aanroepende applicatiecode, en voer daar de tijdzoneconversie uit (met bijvoorbeeld TimeZoneInfo
in .Net of vergelijkbare mechanismen op andere platforms).
ECHTER - je hebt geluk gehad dat Koeweit in een zone ligt (en altijd is geweest) die niet verandert voor zomertijd. Het is altijd UTC+03:00 geweest. U kunt dus eenvoudig drie uur toevoegen en het resultaat retourneren:
SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01'))
Maar besef dat dit geen algemene oplossing is die in elke tijdzone werkt.
Als je wilt, kun je een van de andere SQL-gegevenstypen retourneren, zoals datetimeoffset
, maar dit zal u alleen maar helpen om aan te geven dat de waarde drie uur verschoven is voor wie er ook naar kijkt. Het zal het conversieproces niet anders of beter maken.
Bijgewerkt antwoord
Ik heb een project gemaakt voor het ondersteunen van tijdzones in SQL Server. Je kunt het van hier installeren . Dan kun je gewoon zo converteren:
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait')
U kunt elke tijdzone uit de IANA tz-database gebruiken , inclusief degenen die zomertijd gebruiken.
Je kunt nog steeds de methode gebruiken die ik hierboven heb laten zien om te converteren van een Unix-tijdstempel. Door ze allebei samen te voegen:
SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait')
Opnieuw bijgewerkt
Met SQL Server 2016 is er nu ingebouwde ondersteuning voor tijdzones met de AT TIME ZONE
uitspraak. Dit is ook beschikbaar in Azure SQL Database (v12).
SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time'
Meer voorbeelden in deze aankondiging.