我争论过是否要发布这个,因为它取决于日期在 SQL Server 中的二进制级别是如何存储的,所以这是一个非常脆弱的解决方案。除了一次性转换之外,我会使用类似于@Solution Evangelist 发布的答案。不过,你可能会觉得这在学术上很有趣,所以我还是会发布它。
利用DateTime2 的准确性与.NET 中的滴答持续时间相匹配并且两者都基于01-01-0001 00:00:00.0000000 的开始日期这一事实,您可以将DateTime 转换为DateTime2,并且然后将其转换为binary(9):0x07F06C999F3CB7340B
日期时间信息是 RTL 存储的,所以反过来,我们会得到0x0B34B73C9F996CF007。
前三个字节存储自01-01-0001 以来的天数,接下来的 5 个字节存储自当天午夜以来的 100ns 滴答声,因此我们可以取天数乘以一天中的滴答声并加上表示当天经过的时间的刻度。
执行以下代码:
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]
返回以下结果:
DateTime DateTime2 Ticks
----------------------- ---------------------- --------------------
2011-09-12 07:20:32.587 2011-09-12 07:20:32.58 634514088325870000
获取返回的 Ticks 数量并在 .NET 中转换回 DateTime:
DateTime dt = new DateTime(634514088325870000);
dt.ToString("yyyy-MM-dd HH:mm:ss.fffffff").Dump();
从 sql server 获取我们返回的日期:
2011-09-12 07:20:32.5870000