Den här artikeln innehåller exempel på hur du konverterar en tid värde till en datetimeoffset värde i SQL Server med Transact-SQL.
När du konverterar en tid värde till datetimeoffset , datumet är satt till '1900-01-01' och tiden kopieras. En tidszonsförskjutning läggs till och ställs in på +00:00.
Exempel 1 – Explicit konvertering med CAST()
Här är ett exempel på en explicit konvertering. I det här fallet använder jag CAST()
funktion direkt inom SELECT
uttalande för att uttryckligen konvertera från tid till datetimeoffset .
DECLARE @thetime time; SET @thetime = '23:15:59.1234567'; SELECT @thetime AS 'time', CAST(@thetime AS datetimeoffset) AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.1234567 | 1900-01-01 23:15:59.1234567 +00:00 | +------------------+------------------------------------+
Så en datumdel läggs till och ställs in på '1900-01-01', tiden kopieras och en tidszonförskjutning läggs till och ställs in på +00:00.
Exempel 2 – Precision
I det föregående exemplet använder båda datatyperna sin standardprecision/skala (7). Detta beror på att jag inte har lagt till en skala inom parentes (skalan bestämmer bråksekundersprecisionen). Genom att använda en skala på 7 kan vi se att båda datatyperna kan representera ett tidsvärde som är exakt med 7 decimaler.
Med andra ord, när jag initialt ställde in @thetime
variabel, jag inkluderade 7 decimaler i värdet (specifikt, 1234567
). Både datatyperna "tid" och "datumtidsförskjutning" kunde framgångsrikt representera dessa eftersom de båda använde en skala på 7. Återigen vet vi att de använde 7 eftersom det är standardvärdet.
Bara för att vara tydlig, skala är antalet siffror till höger om decimalkomma i ett tal. Precision är det totala antalet siffror i numret.
Vi kan reducera bråksekundersprecisionen om det behövs.
Här är några exempel som visar vad som händer när datatyperna är inställda på att använda olika bråksekundersprecision:
DECLARE @thetime time(7); SET @thetime = '23:15:59.1234567'; SELECT @thetime AS 'time', CAST(@thetime AS datetimeoffset(0)) AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.1234567 | 1900-01-01 23:15:59.0000000 +00:00 | +------------------+------------------------------------+
I det här fallet ställer jag uttryckligen in @thetime
variabel för att använda en skala på 7. Men när jag kastar detta till datetimeoffset , ställer jag in skalan till 0. Därför blir resultatet för datetimeoffset värdet är mindre bråksekunders precision. På mitt system visas fortfarande 7 decimaler, men alla är 0.
Här är det igen, men den här gången ökar jag bråksekundersprecisionen till 3 för datetimeoffset värde:
DECLARE @thetime time(7); SET @thetime = '23:15:59.1234567'; SELECT @thetime AS 'time', CAST(@thetime AS datetimeoffset(3)) AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.1234567 | 1900-01-01 23:15:59.1230000 +00:00 | +------------------+------------------------------------+
Så den använder de första 3 bråksekunderna (millisekunder).
Men om vi ökar bråksekundersprecisionen till 4, se vad som händer:
DECLARE @thetime time(7); SET @thetime = '23:15:59.1234567'; SELECT @thetime AS 'time', CAST(@thetime AS datetimeoffset(4)) AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.1234567 | 1900-01-01 23:15:59.1235000 +00:00 | +------------------+------------------------------------+
I nästa exempel ökar jag bråkdelens värde så att den orsakar den icke-bråkdeliga delen av datetimeoffset värde som ska avrundas uppåt:
DECLARE @thetime time(7); SET @thetime = '23:15:59.7654321'; SELECT @thetime AS 'time', CAST(@thetime AS datetimeoffset(0)) AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.7654321 | 1900-01-01 23:16:00.0000000 +00:00 | +------------------+------------------------------------+
I det här fallet avrundades minuterna uppåt och sekunderna nollställdes.
Låt oss byta om det så att datetimeoffset har en högre precision än tiden värde:
DECLARE @thetime time(4); SET @thetime = '23:15:59.1234567'; SELECT @thetime AS 'time', CAST(@thetime AS datetimeoffset(7)) AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.1235000 | 1900-01-01 23:15:59.1235000 +00:00 | +------------------+------------------------------------+
Jag deklarerade @thetime
variabeln för att använda en skala på 4, men använde sedan en skala på 7 när den konverterades till datetimeoffset data typ. Att använda en precision på 7 är onödigt, eftersom det inte kan använda en högre precision än vad som redan tilldelats.
En avrundning med lägre precision har dessutom redan inträffat när den omvandlas till datumtidsförskjutningen (med högre precision) data typ. Lägg märke till att tiden datatypen avrundade bråksekunderna uppåt från det initiala värdet som jag tilldelade den. Denna avrundningseffekt flödade också igenom till datetime offset värde.
Exempel 3 – Explicit konvertering med CONVERT()
Här är ett exempel med CONVERT()
funktion istället för CAST()
.
DECLARE @thetime time; SET @thetime = '23:15:59.1234567'; SELECT @thetime AS 'time', CONVERT(datetimeoffset, @thetime) AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.1234567 | 1900-01-01 23:15:59.1234567 +00:00 | +------------------+------------------------------------+
Exempel 4 – Implicit konvertering
Här är ett exempel på att göra samma sak, men med en implicit typkonvertering.
DECLARE @thetime time, @thedatetimeoffset datetimeoffset; SET @thetime = '23:15:59.1234567'; SET @thedatetimeoffset = @thetime; SELECT @thetime AS 'time', @thedatetimeoffset AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.1234567 | 1900-01-01 23:15:59.1234567 +00:00 | +------------------+------------------------------------+
Så vi får samma resultat, oavsett om det är en explicit eller implicit konvertering.
Detta är en implicit konvertering eftersom vi inte använder en konverteringsfunktion för att explicit konvertera den. Vi tilldelar helt enkelt värdet från en variabel av en datatyp till en variabel av en annan datatyp. I det här fallet utför SQL Server en implicit konvertering bakom kulisserna när vi försöker tilldela tiden värde till en datetimeoffset variabel.
Exempel 5 – Ändra datum
Om du behöver ändra datumet (men behålla samma tid), kan du använda DATEADD()
fungera.
DECLARE @thetime time, @thedatetimeoffset datetimeoffset; SET @thetime = '23:15:59.1234567'; SET @thedatetimeoffset = @thetime; SET @thedatetimeoffset = DATEADD(year, 285, @thedatetimeoffset); SELECT @thetime AS 'time', @thedatetimeoffset AS 'datetimeoffset';
Resultat:
+------------------+------------------------------------+ | time | datetimeoffset | |------------------+------------------------------------| | 23:15:59.1234567 | 2185-01-01 23:15:59.1234567 +00:00 | +------------------+------------------------------------+
I det här fallet lägger jag till 285 till årsvärdet, vilket gör att det blir 2185.