J'ai débattu de l'opportunité de publier cela car cela dépend de la façon dont les dates sont stockées au niveau binaire dans SQL Server, et c'est donc une solution très fragile. Pour autre chose qu'une conversion ponctuelle, j'utiliserais quelque chose comme la réponse que @Solution Evangelist a publiée. Néanmoins, vous pourriez trouver cela intéressant d'un point de vue académique, donc je le publierai quand même.
Profitant du fait que la précision de DateTime2
correspond à la durée du tick dans .NET et que les deux sont basés sur des dates de début de 01-01-0001 00:00:00.0000000
, vous pouvez caster le DateTime
à DateTime2
, puis castez-le en binary(9)
:0x07F06C999F3CB7340B
Les informations datetime sont stockées RTL, donc en inversant, nous obtiendrons 0x0B34B73C9F996CF007
.
Les trois premiers octets stockent le nombre de jours depuis 01-01-0001
et les 5 octets suivants stockent les ticks de 100ns depuis minuit de ce jour, nous pouvons donc prendre le nombre de jours, multiplier par les ticks d'un jour et ajouter les ticks représentant le temps écoulé pour la journée.
Exécution du code suivant :
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]
renvoie les résultats suivants :
DateTime DateTime2 Ticks
----------------------- ---------------------- --------------------
2011-09-12 07:20:32.587 2011-09-12 07:20:32.58 634514088325870000
Prendre le nombre de ticks renvoyé et le reconvertir en DateTime dans .NET :
DateTime dt = new DateTime(634514088325870000);
dt.ToString("yyyy-MM-dd HH:mm:ss.fffffff").Dump();
Récupère la date du serveur sql :
2011-09-12 07:20:32.5870000