在不使用DateAdd函数或DateDiff函数的情况下减去两个日期

时间:2017-06-08 10:01:47

标签: sql sql-server sql-server-2008

我如何得到这个输出,你能解释它背后的原因吗?

declare @a datetime = '2017-06-08 16:02:22.467',
        @b datetime = '2017-10-23 00:00:00.000'

select DAY(@a - @b) 

select @a - @b

输出:

17
1899-08-17 16:02:22.467

4 个答案:

答案 0 :(得分:2)

嗯,sql server中的日期存储为自1900-01-01以来的天数 如果您运行此查询,则可以看到它:

SELECT CAST(0 as datetime)

您将获得1900-01-01 00:00:00作为结果。

时间存储为午夜以来的刻度数 每秒有300个滴答。

由于@a中的日期早于@b中的日期,因此您会收到日期(-137)的否定结果,然后将该数字添加到01-01-1900以提供你1899-08-17@a中的时间位于@b之后的时间,由于@b中的时间是午夜,因此您在结果中获得@a的时间。

答案 1 :(得分:0)

当您减去2个日期时,datetime类型的零值为1900-01-01 00:00:00.00

但是从SQL 2008中,microsoft创建了新类型datetime2,并且只要你在此处获得溢出(负值),它就会将结果转换为datetime2来自0001-01-01 00:00:00.00

的统计信息

DAY功能仅从datetimedatetime2类型中获取日期部分。

答案 2 :(得分:0)

declare @a datetime = '2017-06-08 16:02:22.467',
        @b datetime = '2017-10-23 00:00:00.000'

select datediff(day, @a, @b)

它返回137,所以这两天之间的差异是137。

declare @c as datetime = null;
select isnull(@c, 0)

返回1900-01-01 00:00:00.000,表示日期时间的默认值为1900-01-01 00:00:00.000

在您的情况下,此select @a-@b减号操作会使用默认值减去137天的实际差异。

select dateadd(day, -137, '1900-01-01 00:00:00.000')

返回1899-08-17 00:00:00.000

如果是select @b-@a,它将返回1900-05-17 07:57:37.533,即它将从默认值中添加137天。

DAY()函数只返回给定日期的日期。

因此,对于1899-08-17,DAY()应为17

答案 3 :(得分:0)

这将减去两个日期,并将其添加到SQL中的最小日期,即1900-01-01 00:00:00.000'。因此,在减去两个日期并获得差异之后,它将在随后的最小日期中添加它,即1900-01-01 00:00:00.000'。