Ho discusso se pubblicare questo perché dipende da come le date vengono archiviate a livello binario in SQL Server, quindi è una soluzione molto fragile. Per qualcosa di diverso da una conversione una tantum, userei qualcosa come la risposta pubblicata da @Solution Evangelist. Tuttavia, potresti trovarlo interessante da un punto di vista accademico, quindi lo posterò comunque.
Facendo uso del fatto che l'accuratezza di DateTime2
corrisponde alla durata del tick in .NET e che entrambi sono basati su date di inizio di 01-01-0001 00:00:00.0000000
, puoi trasmettere DateTime
a DateTime2
, quindi esegui il cast su binary(9)
:0x07F06C999F3CB7340B
Le informazioni datetime sono memorizzate RTL, quindi invertendo, otterremo 0x0B34B73C9F996CF007
.
I primi tre byte memorizzano il numero di giorni trascorsi da 01-01-0001
e i successivi 5 byte memorizzano i tick di 100ns dalla mezzanotte di quel giorno, quindi possiamo prendere il numero di giorni, moltiplicare per i tick in un giorno e aggiungere i tick che rappresentano il tempo trascorso per la giornata.
Eseguendo il codice seguente:
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]
restituisce i seguenti risultati:
DateTime DateTime2 Ticks
----------------------- ---------------------- --------------------
2011-09-12 07:20:32.587 2011-09-12 07:20:32.58 634514088325870000
Prendendo il numero restituito di tick e riconvertendo in un DateTime in .NET:
DateTime dt = new DateTime(634514088325870000);
dt.ToString("yyyy-MM-dd HH:mm:ss.fffffff").Dump();
Ci riporta la data dal server sql:
2011-09-12 07:20:32.5870000