Jeg diskuterede, om jeg skulle poste dette, fordi det afhænger af, hvordan datoer gemmes på det binære niveau i SQL Server, og det er derfor en meget sprød løsning. Til alt andet end en engangskonvertering ville jeg bruge noget som det svar, som @Solution Evangelist postede. Alligevel vil du måske finde dette interessant på en akademisk måde, så jeg sender det alligevel.
Gør brug af det faktum, at nøjagtigheden af DateTime2
stemmer overens med tick-varigheden i .NET, og at begge er baseret på startdatoer 01-01-0001 00:00:00.0000000
, kan du caste DateTime
til DateTime2
, og cast den derefter til binary(9)
:0x07F06C999F3CB7340B
Dato- og klokkeslætsoplysningerne gemmes RTL, så hvis vi vender om, får vi 0x0B34B73C9F996CF007
.
De første tre bytes gemmer antallet af dage siden 01-01-0001
og de næste 5 bytes gemmer 100ns ticks siden midnat den dag, så vi kan tage antallet af dage, gange med ticks på en dag og tilføje ticks, der repræsenterer den forløbne tid for dagen.
Udførelse af følgende kode:
set @date = getdate()
set @ticksPerDay = 864000000000
declare @date2 datetime2 = @date
declare @dateBinary binary(9) = cast(reverse(cast(@date2 as binary(9))) as binary(9))
declare @days bigint = cast(substring(@dateBinary, 1, 3) as bigint)
declare @time bigint = cast(substring(@dateBinary, 4, 5) as bigint)
select @date as [DateTime], @date2 as [DateTime2], @days * @ticksPerDay + @time as [Ticks]
returnerer følgende resultater:
DateTime DateTime2 Ticks
----------------------- ---------------------- --------------------
2011-09-12 07:20:32.587 2011-09-12 07:20:32.58 634514088325870000
Tager det returnerede antal kryds og konverterer tilbage til en DateTime i .NET:
DateTime dt = new DateTime(634514088325870000);
dt.ToString("yyyy-MM-dd HH:mm:ss.fffffff").Dump();
Får os datoen tilbage fra sql-serveren:
2011-09-12 07:20:32.5870000