CAST(hex_num AS DateTime) - SQL Server 2008 R2

时间:2013-01-29 17:05:29

标签: sql-server datetime

导出数据时(rclick db | Tasks | Generate scripts ...)datetime列以这种方式导出:

CAST(0xFFFF2E4600000000 AS DateTime)

select CAST(0xFFFF2E4600000000 AS DateTime)

..在SQL Server Mgmt Studio中我得到:

1753-01-01 00:00:00.000

我需要在另一个程序中将此(即0xFFFF2E4600000000)转换为常规日期时间。

现在,我知道格式在1900年1月1日之后的日期是如何工作的:

first 4 bytes == the days since 1st Jan 1900
2nd 4 bytes == number of ticks since midnight (each tick is 1/300 of a second).

这有效,但我无法弄清楚上面的十六进制数(0xFFFF2E4600000000)如何转换为1753-01-01。 2的补充,在1900年到1753年之间的各种变换等 - 没有任何作用。谷歌搜索结果它对我不利也没有帮助。请指教!

更新

似乎无论如何都要使用2的补码,请参阅以下内容,但在Python shell中它仍然不能正常工作:

>>> e=1900-1753
>>> e
147
>>> 
>>> e*=365
>>> e
53655
>>> e=e-(1<<32)
>>> e
-4294913641L
>>> hex(e)
'-0xffff2e69L'

那是接近0xFFFF2E46但不完全存在。这是怎么回事?

更新2:

闰日?

1 个答案:

答案 0 :(得分:0)

对我来说很好看:

declare @Sample as DateTime = '1753-01-01'
select @Sample as 'Sample', Cast( @Sample as VarBinary(8) ) as 'VarBinary',
  DateDiff( day, '1900-01-01', @Sample ) as 'DateDiff',
  Cast( DateDiff( day, '1900-01-01', @Sample ) as VarBinary(4) ) as 'Hex DateDiff'

请注意,十六进制值被视为带符号的32位值。

如果问题是“为什么53,690?”然后答案是:

; with Years as (
  select 1753 as Year, 0 as LeapYear
  union all
  select Year + 1,
    case
     when ( Year + 1 ) % 400 = 0 then 1
     when ( Year + 1 ) % 100 = 0 then 0
     when ( Year + 1 ) % 4 = 0 then 1
     else 0 end
    from Years
    where Year < 1900 )
  select 147 * 365 + Sum( LeapYear ) as Days from Years
  option ( maxrecursion 0 )