我想进入一个存储过程,在最高小时或最低小时截断时间戳输入值。
例如,如果我的输入值为2020-02-12 06:56:00and 2020-02-12 07:14:00,我想将其转换为2020-02-12 06:00:00and2020-02-12 08:00:00
强制转换函数可以工作吗?
我想进入一个存储过程,在最高小时或最低小时截断时间戳输入值。
例如,如果我的输入值为2020-02-12 06:56:00and 2020-02-12 07:14:00,我想将其转换为2020-02-12 06:00:00and2020-02-12 08:00:00
强制转换函数可以工作吗?
您可以从您想要的原始日期时间部分构建新的日期时间。
declare @start datetime = '2020-02-12 06:56:00'
declare @end datetime = '2020-02-12 07:14:00'
select @start as OriginalStart,
@end as OriginalEnd,
datetimefromparts(year(@start), month(@start), day(@start), datepart(hour, @start), 0, 0, 0) as TruncatedStart,
dateadd(hour, 1, datetimefromparts(year(@end), month(@end), day(@end), datepart(hour, @end), 0, 0, 0)) as TruncatedEnd
间隔的第一个截断是较低的小时,第二个截断增加一个额外的小时,因此它返回较高的小时。
PS:如果您想要四舍五入到最接近的小时,那么您可以添加 30 分钟并截断:
declare @date datetime = '2020-02-12 06:56:00'
set @date = dateadd(minute, 30, @date)
select datetimefromparts(year(@date), month(@date), day(@date), datepart(hour, @date), 0, 0, 0) as NearestHour
或一步(使用 Lepetit 的截断快捷方式):
declare @date datetime = '2020-02-12 06:56:00'
select dateadd(hour, datediff(hour, 0, dateadd(minute, 30, @date)), 0) AS NearestHour
使用一点算术计算,转换为带小数的小时并使用floor()andceiling()执行向上/向下舍入
首先,它发现时间与00:00:00秒不同。convert(date, date_col)将日期时间转换为日期,因此有效的是00:00:00
datediff(second, convert(date, date_col), date_col)
然后你除以60 x 60 = 3600秒。给你几个小时
然后你使用floor()orceiling()来执行舍入
最后你把它加回日期(convert(date, date_col))
最终查询
select *,
RoundDown = convert(datetime, convert(date, date_col))
+ dateadd(hour, floor(datediff(second, convert(date, date_col), date_col) / (3600.0)), 0),
RoundUp = convert(datetime, convert(date, date_col))
+ dateadd(hour, ceiling(datediff(second, convert(date, date_col), date_col) / (3600.0)), 0)
from (
values
('2020-02-12 06:56:00'),
('2020-02-12 07:14:00')
) d (date_col)
/*
2020-02-12 06:56:00 2020-02-12 06:00:00 2020-02-12 07:00:00
2020-02-12 07:14:00 2020-02-12 07:00:00 2020-02-12 08:00:00
*/
编辑:下面有一个更简单的查询
找出minute除以60.0分钟的差异,以获得不同的小时(带小数位),然后应用flooror ceiling。最后将该结果添加回来
select getdate() as Now,
dateadd(hour, floor(datediff(minute, 0, getdate()) / 60.0), 0) as RoundDown,
dateadd(hour, ceiling(datediff(minute, 0, getdate()) / 60.0), 0) as RoundUp
这是一个更简单的解决方案:
declare @start datetime = '2020-02-12 06:56:00'
declare @end datetime = '2020-02-12 07:14:00'
select @start as OriginalStart,
@end as OriginalEnd,
dateadd(hour, datediff(hour, 0, @start), 0) as TruncatedStart,
dateadd(hour, datediff(hour, 0, dateadd(hour, 1, @end)), 0) as TruncatedEnd
在这两种情况下,该函数都会从原始时间戳中减去小时部分。对于 TruncatedEnd,增加一小时,因此结果是下一小时。