如何比较不同精度的日期
How to compare dates with different precision
我问 如何比较 datetime2
值,但忽略了纳秒。由于涉及一些舍入,因此无法正确比较这些值。
在 java 中,我可以从 Date
和 Timestamp
中得到一个 Long
值,它表示自 1970 年 1 月 1 日以来的毫秒数,00:00:00格林威治标准时间。这是比较 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))
来获得最精确的结果,但由于四舍五入,它们仍然不匹配。
任何人都可以给我一个方便的方法来比较上面的值以匹配吗?
您可以通过从未舍入的日期中提取毫秒数来执行此操作,使用取模函数从 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
为了完整性,这里和正常的四舍五入、四舍五入、四舍五入是一样的
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);
一个快速的选择是转换为 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
Returns
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
我问 datetime2
值,但忽略了纳秒。由于涉及一些舍入,因此无法正确比较这些值。
在 java 中,我可以从 Date
和 Timestamp
中得到一个 Long
值,它表示自 1970 年 1 月 1 日以来的毫秒数,00:00:00格林威治标准时间。这是比较 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))
来获得最精确的结果,但由于四舍五入,它们仍然不匹配。
任何人都可以给我一个方便的方法来比较上面的值以匹配吗?
您可以通过从未舍入的日期中提取毫秒数来执行此操作,使用取模函数从 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
为了完整性,这里和正常的四舍五入、四舍五入、四舍五入是一样的
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);
一个快速的选择是转换为 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
Returns
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