Debatí si publicar esto porque depende de cómo se almacenan las fechas en el nivel binario en SQL Server, por lo que es una solución muy frágil. Para cualquier cosa que no sea una conversión única, usaría algo como la respuesta que publicó @Solution Evangelist. Aun así, es posible que encuentres esto interesante desde un punto de vista académico, así que lo publicaré de todos modos.
Haciendo uso del hecho de que la precisión de DateTime2
coincide con la duración del tick en .NET y ambos se basan en las fechas de inicio de 01-01-0001 00:00:00.0000000
, puede emitir el DateTime
a DateTime2
, y luego transfiéralo a binary(9)
:0x07F06C999F3CB7340B
La información de fecha y hora se almacena RTL, por lo que al invertir obtendremos 0x0B34B73C9F996CF007
.
Los primeros tres bytes almacenan el número de días desde 01-01-0001
y los siguientes 5 bytes almacenan los ticks de 100 ns desde la medianoche de ese día, por lo que podemos tomar la cantidad de días, multiplicar por los ticks en un día y agregar los ticks que representan el tiempo transcurrido del día.
Ejecutando el siguiente código:
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]
devuelve los siguientes resultados:
DateTime DateTime2 Ticks
----------------------- ---------------------- --------------------
2011-09-12 07:20:32.587 2011-09-12 07:20:32.58 634514088325870000
Tomando el número de Ticks devuelto y convirtiéndolo de nuevo a DateTime en .NET:
DateTime dt = new DateTime(634514088325870000);
dt.ToString("yyyy-MM-dd HH:mm:ss.fffffff").Dump();
Nos devuelve la fecha del servidor sql:
2011-09-12 07:20:32.5870000