Uppdaterat svar
Jag har skrivit verktyget jag talade om i det ursprungliga svaret, som du hittar här .
Från och med SQL Server 2016 (och Azure SQL Database) kan du nu använda AT TIME ZONE
nyckelord för att konvertera mellan tidszoner.
Originalt svar
Tyvärr finns det ingen bra lösning för att arbeta med tidszoner i SQL Server.
Jag har undersökt problemet du länkade noggrant, tillsammans med denna
också. Det finns inga inbyggda tidszonsfunktioner och all användning av TimeZoneInfo
i SQLCLR kräver att sammansättningen är registrerad som "osäker". Detta är vanligtvis inte önskvärt.
Jag undersökte också med Noda Time från SQLCLR. Du kan läsa om det i det här numret . Det måste också registreras som "osäkert" på grund av hur vissa objekt cachelagras internt.
I slutändan, med båda objekten, är problemet att det inte finns något sätt att cachelagra något i SQLCLR. Du kan inte använda statiska variabler på ett trådsäkert sätt, och du kan inte göra någon trådsynkronisering eller använda klasser som ConcurrentDictionary
. SQL vill ha full kontroll över gängningsmodellen för sammansättningen. Endast enkelgängad användning-en gång-och-släng-stilkod fungerar i "säkra" sammansättningar. Jag grävde djupt i detta i den här frågan:Multithreaded caching i SQL CLR
Förhoppningsvis kommer det så småningom vara en build av Noda Time som kommer att fungera i SQLCLR, men det kommer att vara en speciell build som inte gör någon cachning. Så det kommer inte att fungera lika snabbt, men det kommer att få jobbet gjort samtidigt som det är säkert.
TimeZoneInfo
kommer sannolikt inte att förändras. Så om inte SQL Server-teamet någonsin tar med tidszonsfunktioner direkt till SQL Server på rätt sätt (som Oracle och Postgres gör), så har du bara några få alternativ:
-
Försök inte konvertera tidszoner i datalagret. Arbeta med
datetime
ellerdatetime2
värden i UTC, eller använddatetimeoffset
värden med någon offset. Men gör alla konverteringar mellan tidszoner i applikationslagret. Detta är min bästa rekommendation för tillfället. -
Kopiera all data för tidszonerna till faktiska SQL-tabeller och skriv funktioner som fungerar med dessa data. Detta är inte den bästa idén, eftersom data ändras ofta så tabellunderhåll kan vara en utmaning. Det kan också vara svårt att få funktionerna korrekta, inklusive alla regler för sommartidsändringar. Jag känner inte till något projekt som har det här snyggt och snyggt, men om någon är det - låt mig gärna veta i kommentarerna.
-
Aktivera
xp_regread
och arbeta med tidszonsdata direkt från Windows registernycklar. Uppdateringar skulle göras åt dig, men du har fortfarande samma utmaningar när du skriver dessa funktioner. Och att aktivera registerläsning kan vara en lika stor säkerhetsrisk som att aktivera osäkra CLR-sammansättningar ändå.
En annan idé jag funderar på är att skriva en IANA/Olson TZDB parser och funktioner specifikt för SQL Server. Detta skulle likna alternativ 2 ovan, men gjort på ett underhållbart sätt och med IANA standarddata istället för Windows tidszoner. Kanske kommer jag till det här någon gång, eller så kanske någon slår mig till det. Återigen, jag känner inte till något aktuellt projekt som gör detta, men om någon känner till ett, vänligen meddela mig i kommentarerna. (klar – se uppdatering högst upp )
Angående SWITCHOFFSET
- det fungerar bara när du redan känner till målförskjutningen. Det är halva striden, och förmodligen därför Microsoft fortfarande markerar datetimeoffset
som inte "sommartid medveten" i dokumenten
.