这是存储在SQL Server中的十六进制值的查询:
select CAST(0x00EF290000000000 AS Time)
输出:
02:58:55.0000000
我在Python中将此十六进制值转换为时间格式。但我没有得到这个十六进制值结构的任何规范,比如我应该使用多少字节,是小端还是大印度,秒后小数点值如何(02:58:55.xxxxxx) 。
我得到了date,datetime,datetime2的规范,但是时间数据类型十六进制值转换没有运气。这个十六进制值的时间是否有任何规范?请帮帮我,谢谢。
答案 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。因为您要转换为29ef
(TIME
没有显式比例),所以对于小数部分显示7位精度,即使它们不在输入中。
我希望上面的内容表明,无论你的语言如何,你都可以在字符串和背后转换TIME(7)
,而不是使用二进制表示。 TIME
可以被我所知道的任何语言和框架解析,并且在SQL Server版本中保持可靠。相反,将02:58:55
转换为01:23:45.6789012
则涉及更多内容。除非您正在实现TDS解析器,否则我无法想到您希望转换在 SQL Server外部的值的二进制表示形式的任何情况。
示例C#代码将二进制值转换为100 ns刻度:
0x0714BE89B30B
此代码中省略了验证输入。它只是为了演示逻辑(并且应该很容易翻译成其他语言);不要在生产中按原样使用它。