SQL Server将十六进制时间值转换为可读时间格式

时间:2016-04-22 13:17:59

标签: sql-server casting hex

这是存储在SQL Server中的十六进制值的查询:

select CAST(0x00EF290000000000 AS Time)

输出:

02:58:55.0000000

我在Python中将此十六进制值转换为时间格式。但我没有得到这个十六进制值结构的任何规范,比如我应该使用多少字节,是小端还是大印度,秒后小数点值如何(02:58:55.xxxxxx) 。

我得到了date,datetime,datetime2的规范,但是时间数据类型十六进制值转换没有运气。这个十六进制值的时间是否有任何规范?请帮帮我,谢谢。

1 个答案:

答案 0 :(得分:0)

Validator.validateValue的二进制表示的规范可以从TDS protocol specification派生。从技术上讲,TIME中使用的格式没有理由与TDS规范相匹配,但实际上这种对应关系非常可靠。

第2.2.5.4.2节:

  

对于TIMENTYPE,唯一有效的长度(以及相关的比例)   价值)是:

SCALE  |    1 |    2 |    3 |    4 |    5 |    6 |    7 |
LENGTH | 0x03 | 0x03 | 0x04 | 0x04 | 0x05 | 0x05 | 0x05 |

(由于某种原因,标度0缺失,即使它有效。)

和2.2.5.5.1.8:

  

time(n)表示为一个无符号整数,表示自上午12点以来10 - n 秒增量的数量   天。该整数的长度(以字节为单位)取决于 n 的比例   如下:

     
      
  • 如果0 <= n <= 2,则为3个字节。
  •   
  • 4个字节,如果3&lt; = n&lt; = 4。
  •   
  • 5个字节,如果5&lt; = n&lt; = 7。
  •   

此整数的字节顺序为little-endian,如2.2.5.1中所述。

在上面的例子中,CONVERT的第一个字节是指定剩余长度(3个字节)的标度(0),意味着小尾数中的无符号整数0x00EF290000000000表示数字10 -0 秒增量。 0xef2900十六进制是10735,而午夜过去的10735秒确实是02:58:55。因为您要转换为29efTIME没有显式比例),所以对于小数部分显示7位精度,即使它们不在输入中。

我希望上面的内容表明,无论你的语言如何,你都可以在字符串和背后转换TIME(7),而不是使用二进制表示。 TIME可以被我所知道的任何语言和框架解析,并且在SQL Server版本中保持可靠。相反,将02:58:55转换为01:23:45.6789012则涉及更多内容。除非您正在实现TDS解析器,否则我无法想到您希望转换 SQL Server外部的值的二进制表示形式的任何情况。

示例C#代码将二进制值转换为100 ns刻度:

0x0714BE89B30B

此代码中省略了验证输入。它只是为了演示逻辑(并且应该很容易翻译成其他语言);不要在生产中按原样使用它。