如何比较不同精度的日期

时间:2018-01-29 13:41:48

标签: sql-server datetime datetime2

我问this question有关如何比较datetime2值但忽略纳秒的问题。由于涉及一些舍入,因此无法正确比较这些值。

在java中,我可以从LongDate获得Timestamp - 值,表示自1970年1月1日00:00:00 GMT以来的毫秒数。这是比较java中日期的一种非常安全的方法。

有没有办法

A)从datetime2值获取一个数值,该值代表毫秒数

B)改变从毫秒到舍入而不是向上的舍入。

示例值:

2018-01-24 16:20:51.0715460
2018-01-25 09:52:04.1946950
2018-01-25 09:52:04.1946950

应与

匹配
2018-01-24 16:20:51.0710000
2018-01-25 09:52:04.1940000
2018-01-25 09:52:04.1940000

目前我正在使用cast(date as datetime2(3))来获得最准确的结果,但由于四舍五入,它们仍然无法匹配。

有人能给我一个方便的方法来比较上面的值来匹配吗?

2 个答案:

答案 0 :(得分:2)

你可以通过提取未离开日期的毫秒数,使用模数函数从1000000获得余数,然后从原始日期中扣除,例如

SELECT  A,
        B,
        RoundDown = DATEADD(NANOSECOND, -DATEPART(NANOSECOND, A) % 1000000, A),
        Match = CASE WHEN DATEADD(NANOSECOND, -DATEPART(NANOSECOND, A) % 1000000, A) = B THEN 1 ELSE 0 END
FROM    (VALUES
            (CONVERT(DATETIME2(7), '2018-01-24 16:20:51.0715460'), CONVERT(DATETIME2(7), '2018-01-24 16:20:51.0710000')),
            (CONVERT(DATETIME2(7), '2018-01-25 09:52:04.1946950'), CONVERT(DATETIME2(7), '2018-01-25 09:52:04.1940000')),
            (CONVERT(DATETIME2(7), '2018-01-25 09:52:04.1946950'), CONVERT(DATETIME2(7), '2018-01-25 09:52:04.1940000'))
        ) x (A, B);

给出:

A                               B                               RoundDown                       Match
-------------------------------------------------------------------------------------------------------
2018-01-24 16:20:51.0715460     2018-01-24 16:20:51.0710000     2018-01-24 16:20:51.0710000     1
2018-01-25 09:52:04.1946950     2018-01-25 09:52:04.1940000     2018-01-25 09:52:04.1940000     1
2018-01-25 09:52:04.1946950     2018-01-25 09:52:04.1940000     2018-01-25 09:52:04.1940000     1

对于comleteness,这是正常舍入,四舍五入和四舍五入的相同事情

SELECT  Original = A,
        RoundDown = DATEADD(NANOSECOND, -DATEPART(NANOSECOND, A) % 1000000, A),
        RoundUp = DATEADD(NANOSECOND, 1000000 - DATEPART(NANOSECOND, A) % 1000000, A),
        RoundNormal = CONVERT(DATETIME2(3), A)
FROM    (VALUES
            (CONVERT(DATETIME2(7), '2018-01-24 16:20:51.0715460')),
            (CONVERT(DATETIME2(7), '2018-01-25 09:52:04.1946950')),
            (CONVERT(DATETIME2(7), '2018-01-25 09:52:04.1946950')),
            (CONVERT(DATETIME2(7), '2018-01-25 09:52:04.1943950'))
        ) x (A);

答案 1 :(得分:1)

一个快速选项是转换为varchar(23),这将基本上截断值

示例

Declare @YourTable Table ([D1] datetime2)
Insert Into @YourTable Values 
 ('2018-01-24 16:20:51.0715460')
,('2018-01-25 09:52:04.1946950')
,('2018-01-25 09:52:04.1946950')

Select * 
      ,NewVal = convert(varchar(23),D1)+'0000'
from @YourTable

返回

D1                             NewVal
2018-01-24 16:20:51.0715460    2018-01-24 16:20:51.0710000
2018-01-25 09:52:04.1946950    2018-01-25 09:52:04.1940000
2018-01-25 09:52:04.1946950    2018-01-25 09:52:04.1940000