Denne artikel ser på de vigtigste forskelle mellem datetime2 og datotidsforskydning datatyper i SQL Server.
Begge datatyper bruges til lagring af dato- og tidsværdier. Begge er meget ens, men med én nøgleforskel; datotidsforskydningen gemmer tidszoneforskydningen.
Dette resulterer også i datetime offset bruger mere lagerplads end datetime2 , så du ville kun bruge datetime offset hvis du har brug for tidszoneforskydning.
Her er en tabel, der skitserer de vigtigste forskelle mellem disse to typer.
Funktion | datetime offset | datetime2 |
---|---|---|
SQL-kompatibel (ANSI &ISO 8601) | Ja | Ja |
Datointerval | 0001-01-01 til 9999-12-31 | 0001-01-01 til 9999-12-31 |
Tidsinterval | 00:00:00 til 23:59:59.9999999 | 00:00:00 til 23:59:59.9999999 |
Tegnlængde | 26 positioner minimum 34 maksimum | 19 stillinger minimum 27 maksimum |
Lagerstørrelse | 8 til 10 bytes, afhængig af præcisionen* * Plus 1 byte til at gemme præcisionen | 6 til 8 bytes, afhængig af præcisionen* * Plus 1 byte til at gemme præcisionen |
Nøjagtighed | 100 nanosekunder | 100 nanosekunder |
Brøksekundpræcision | Ja | Ja |
Brugerdefineret brøksekundpræcision | Ja | Ja |
Tidszoneforskydningsområde | -14:00 til +14:00 | Ingen |
Opmærksomhed og bevarelse af tidszoneforskydning | Ja | Nej |
Sommertid opmærksom på | Nej | Nej |
Skal jeg bruge 'datetime2' eller 'datetime offset'?
Dette afhænger af, om du skal inkludere en tidszoneforskydning eller ej.
Hvis du skal inkludere en tidszoneforskydning, skal du bruge datetimeoffset .
Hvis ikke, så brug datetime2 , da du sparer lagerplads og eliminerer eventuelle problemer med at have en (potentielt forkert) tidszoneforskydning i dine data.
Eksempel 1 – Grundlæggende sammenligning
Her er et hurtigt eksempel til at demonstrere den grundlæggende forskel mellem datetime2 og datotidsforskydning .
DECLARE @thedatetimeoffset datetimeoffset(7), @thedatetime2 datetime2(7); SET @thedatetimeoffset = '2025-05-21 10:15:30.5555555 +07:30'; SET @thedatetime2 = @thedatetimeoffset; SELECT @thedatetimeoffset AS 'datetimeoffset', @thedatetime2 AS 'datetime2';
Resultat:
+------------------------------------+-----------------------------+ | datetimeoffset | datetime2 | |------------------------------------+-----------------------------| | 2025-05-21 10:15:30.5555555 +07:30 | 2025-05-21 10:15:30.5555555 | +------------------------------------+-----------------------------+
Her indstiller jeg en datetime2 variabel til samme værdi som datetime offset variabel. Dette får værdien til at blive konverteret til datetime2 og vi kan derefter bruge en SELECT
sætning for at se værdien af hver variabel.
Begge variabler bruger en skala fra 7, hvilket betyder, at de har 7 decimaler.
Så i dette tilfælde er den eneste forskel mellem de to, at datetime offset værdien inkluderer tidszoneforskydningen og datetime2 værdi ikke.
Eksempel 2 – Ændring af præcisionen
Begge typer giver dig mulighed for at angive en præcision (ved at bruge en skala mellem 0 og 7). Derfor er det muligt at indstille datetime2 værdi med en lavere præcision end datotidsforskydningen værdi (og omvendt).
Eksempel:
DECLARE @thedatetimeoffset datetimeoffset(7), @thedatetime2 datetime2(3); SET @thedatetimeoffset = '2025-05-21 10:15:30.5555555 +07:30'; SET @thedatetime2 = @thedatetimeoffset; SELECT @thedatetimeoffset AS 'datetimeoffset', @thedatetime2 AS 'datetime2';
Resultat:
+------------------------------------+-------------------------+ | datetimeoffset | datetime2 | |------------------------------------+-------------------------| | 2025-05-21 10:15:30.5555555 +07:30 | 2025-05-21 10:15:30.556 | +------------------------------------+-------------------------+
Her indstiller jeg datetime2 værdi til en skala fra 3, hvilket betyder, at den ender med 3 decimaler i stedet for 7. I dette tilfælde rundes dens brøksekunder op (fordi det næste brøkciffer er 5 eller højere).
Så vi kan se, at det er muligt at få en anden dato/tidsværdi afhængigt af de brøksekunder, som vi tildeler datetime2 . Dette fungerer også den anden vej (f.eks. hvis vi konverterer fra datetime2(7) til datetimeoffset(3) ).
Men hvis vi reducerer brøkdelen, udføres der ingen afrunding:
DECLARE @thedatetimeoffset datetimeoffset(7), @thedatetime2 datetime2(3); SET @thedatetimeoffset = '2025-05-21 10:15:30.5554444 +07:30'; SET @thedatetime2 = @thedatetimeoffset; SELECT @thedatetimeoffset AS 'datetimeoffset', @thedatetime2 AS 'datetime2';
Resultat:
+------------------------------------+-------------------------+ | datetimeoffset | datetime2 | |------------------------------------+-------------------------| | 2025-05-21 10:15:30.5554444 +07:30 | 2025-05-21 10:15:30.555 | +------------------------------------+-------------------------+
Eksempel 3 – Indstilling af værdier fra strenge bogstaver
I de foregående eksempler er datetime2 værdien blev tildelt ved at indstille den til den samme værdi som datetime offset værdi. Når vi gør det, udfører SQL Server en implicit konvertering for at dataene "passer" til den nye datatype.
Vi kan også tildele den samme værdi direkte til datetime2 variabel (selvom den officielle dokumentation ikke eksplicit angiver, at den accepterer en streng-literal med en tidszoneforskydning):
DECLARE @thedatetimeoffset datetimeoffset(7), @thedatetime2 datetime2(7); SET @thedatetimeoffset = '2025-05-21 10:15:30.5555555 +07:30'; SET @thedatetime2 = '2025-05-21 10:15:30.5555555 +07:30'; SELECT @thedatetimeoffset AS 'datetimeoffset', @thedatetime2 AS 'datetime2';
Resultat:
+------------------------------------+-----------------------------+ | datetimeoffset | datetime2 | |------------------------------------+-----------------------------| | 2025-05-21 10:15:30.5555555 +07:30 | 2025-05-21 10:15:30.5555555 | +------------------------------------+-----------------------------+
Eksempel 4 – Lagerstørrelse
datetime2 datatypen bruger to bytes mindre lagerplads end datetimeoffset for enhver given præcision.
datetime2 kan være enten 6, 7 eller 8 bytes, afhængigt af dens præcision.
datetime offset kan være enten 8, 9 eller 10 bytes, afhængigt af dens præcision.
Microsoft oplyser, at datetime2 type bruger også 1 ekstra byte for at gemme sin præcision, i hvilket tilfælde den ville bruge mindst 3 bytes mere end smalldatetime .
Dette gælder også for datetime offset (selvom det ikke er eksplicit angivet i Microsoft-dokumentationen).
Det afhænger dog af, om vi gemmer det i en tabel eller i en variabel, og om vi konverterer det til en binær konstant eller ej.
Her er, hvad der sker, hvis vi bruger DATALENGTH()
funktion til at returnere antallet af bytes brugt for hver af vores værdier:
DECLARE @thedatetimeoffset datetimeoffset(7), @thedatetime2 datetime2(7); SET @thedatetimeoffset = '2025-05-21 10:15:30.5555555 +07:30'; SET @thedatetime2 = @thedatetimeoffset; SELECT DATALENGTH(@thedatetimeoffset) AS 'datetimeoffset', DATALENGTH(@thedatetime2) AS 'datetime2';
Resultat
+------------------+-------------+ | datetimeoffset | datetime2 | |------------------+-------------| | 10 | 8 | +------------------+-------------+
Som forventet, 10 bytes til datetime offset og 8 bytes for datetime2 .
Men hvis vi konverterer dem til varbinary , får vi følgende:
DECLARE @thedatetimeoffset datetimeoffset(7), @thedatetime2 datetime2(7); SET @thedatetimeoffset = '2025-05-21 10:15:30.5555555 +07:30'; SET @thedatetime2 = @thedatetimeoffset; SELECT DATALENGTH(CAST(@thedatetimeoffset AS varbinary(16))) AS 'datetimeoffset', DATALENGTH(CAST(@thedatetime2 AS varbinary(16))) AS 'datetime2';
Resultat
+------------------+-------------+ | datetimeoffset | datetime2 | |------------------+-------------| | 11 | 9 | +------------------+-------------+
En ekstra byte tilføjes til hver værdi for at gemme præcisionen.
Mange udviklere antager, at konvertering til varbinary er repræsentativ for, hvordan SQL Server faktisk gemmer dato- og tidsværdier. Dette er dog kun delvist sandt.
Selvom det er rigtigt, at SQL Server gemmer sine dato- og tidsværdier i hexadecimal, inkluderer denne hex-værdi faktisk ikke præcisionen. Dette skyldes, at præcisionen indgår i kolonnedefinitionen. Men når vi konverterer til varbinary ligesom vi gjorde i det foregående eksempel, er præcisionen forudsat, og dette tilføjer en ekstra byte.
For flere detaljer om, hvordan disse datatyper gemmes i forskellige sammenhænge, se følgende artikler:
- Forståelse af 'datetimeoffset'-lagerstørrelse i SQL Server
- Forståelse af 'datetime2'-lagerstørrelse i SQL Server