Jag diskuterade om jag skulle lägga upp det här eftersom det beror på hur datum lagras på binär nivå i SQL Server, och så det är en mycket spröd lösning. För allt annat än en engångskonvertering skulle jag använda något liknande svaret som @Solution Evangelist postade. Ändå kanske du tycker att det här är intressant på ett akademiskt sätt, så jag lägger upp det ändå.
Att använda sig av det faktum att noggrannheten för DateTime2
stämmer överens med tick-varaktigheten i .NET och att båda är baserade på startdatum 01-01-0001 00:00:00.0000000
, kan du casta DateTime
till DateTime2
, och casta den sedan till binary(9)
:0x07F06C999F3CB7340B
Datetime-informationen lagras RTL, så omvänds, får vi 0x0B34B73C9F996CF007
.
De första tre byten lagrar antalet dagar sedan 01-01-0001
och de nästa 5 byten lagrar 100ns tickarna sedan midnatt den dagen, så vi kan ta antalet dagar, multiplicera med ticks på en dag och lägga till ticks som representerar tiden som förflutit för dagen.
Kör följande kod:
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]
returnerar följande resultat:
DateTime DateTime2 Ticks
----------------------- ---------------------- --------------------
2011-09-12 07:20:32.587 2011-09-12 07:20:32.58 634514088325870000
Ta det returnerade antalet Ticks och konvertera tillbaka till en DateTime i .NET:
DateTime dt = new DateTime(634514088325870000);
dt.ToString("yyyy-MM-dd HH:mm:ss.fffffff").Dump();
Får oss tillbaka datumet från sql-servern:
2011-09-12 07:20:32.5870000