TSQL日期时间转换会丢失一段时间

时间:2017-11-15 16:33:40

标签: sql tsql datetime type-conversion sql-server-2014

我正在使用MsSQL Server几天了,当将日期时间转换为/从小数时,偶然发现了一种奇怪的行为。

SELECT [date] = GETDATE()

, [as decimal] = CAST(GETDATE() AS decimal)
, [from decimal] = CAST(CAST(GETDATE() AS decimal) AS datetime)

, [as float] = CAST(GETDATE() AS float)
, [from float] = CAST(CAST(GETDATE() AS float) AS datetime)

--                                  should be: 2009-08-15
, [from stored float] = CAST(CAST('40039.9583333333' AS float) AS datetime)

当我转换日期时间而不添加任何特定的小数时,将处理小数,因为我将其定义为十进制(18,0)。 So there is a data loss in some way.

如果我直接将一个浮点数转换回从日期时间转换的日期时间(如我的查询的第7行所示),一切都很好。

但是当我从数据库表中加载一个值时,例如40039.9583333333,它肯定是从用户输入(2009-08-15)计算出来并将其转换回日期时间,它会添加一天。

我无法找到任何具体的时间损失。

有人能够描述这种奇怪行为背后的问题吗? 并且,如果可能的话 添加一个关于如何正确执行这些转换的示例?

感谢。

3 个答案:

答案 0 :(得分:1)

我使用了您指定的值' 2009-08-15'并将其转换为十进制和浮点数,两者的值均为40038。我使用此值转换回日期时间,并且十进制和浮点数返回' 2009-08-15 00:00:00.000'。

值40039.9583333333导致,正如Renan刚刚发布的那样:),' 2009-08-16 22:59:59.997'。

我会怀疑它是否绝对是根据用户输入计算的(2009-08-15)'因为事实并非如此。除此之外还有更多内容。

-- Microsoft SQL Server 2014 - 12.0.4100.1 (X64)

DECLARE @dt datetime = '2009-08-15'

SELECT CAST(@dt AS decimal) -- 40038
SELECT CAST(@dt AS float) -- 40038

DECLARE @dec1 decimal = 40038;
SELECT CAST(@dec1 AS datetime) -- 2009-08-15 00:00:00.000
DECLARE @flo1 float = 40038;
SELECT CAST(@flo1 AS datetime) -- 2009-08-15 00:00:00.000

DECLARE @dec2 decimal = 40039.9583333333;
SELECT CAST(@dec2 AS datetime) -- 2009-08-17 00:00:00.000
DECLARE @flo2 float = 40039.9583333333;
SELECT CAST(@flo2 AS datetime) -- 2009-08-16 22:59:59.997

答案 1 :(得分:0)

您在数据库中的输入源是什么?根本问题可能是该日期的起始参考点。

作为一个例子:从在线阅读,在Excel中的日期值' 1900-01-01'在数字上等于1。

但是,在SQL Server中日期值' 1900-01-01'在数字上等于0。

SELECT CAST(CAST('1900-01-01' AS DATETIME) AS FLOAT)

答案 2 :(得分:0)

在SQL Server中40039.9583333333SELECT CAST(CAST('2009-08-16 23:00' AS DATETIME) AS FLOAT)

的结果

您应该检查输入。检查正在使用的比例/代码来计算存储在表格中的值。