基于UTC+1时间字段生成小时上下限出错,求代码修正
现有基于UTC-6的日期字段date_utc_minus_6,已将其转换为UTC+1的date_utc_1字段,需生成该UTC+1时间的小时截断上下限字段,示例如下:
RECORD 1 :
date_utc_minus_6 = 02/07/2024 8:15 AM
date_utc_1 = 02/07/2024 2:15 PM
field_lower_limit = 02/07/2024 2:00 PM
field_upper_limit = 02/07/2024 3:00 PM
尝试以下代码:
GETDATE() as date_utc_minus_6, /*system date field*/ date_utc_minus_6 AT TIME ZONE 'Central Standard Time' AT TIME ZONE 'Central European Standard Time' AS date_utc_1, DATEADD(hour, DATEDIFF(hour, 1, date_utc_1), 0) as field_lower_limit, DATEADD(hour, 1, field_lower_limit) as field_upper_limit
但运行后得到的结果日期为2月6日而非预期的7日,临时通过加1天的代码实现了预期效果,但对该方案存疑,寻求代码修正方法。
问题出在小时截断的逻辑上:DATEDIFF(hour, 1, date_utc_1)中的参数1会被SQL Server解析为1900-01-01 01:00:00(基准时间1900-01-01 00:00:00加1小时),计算该时间到date_utc_1的小时差后,再通过DATEADD加到基准时间0(1900-01-01 00:00:00),相当于把date_utc_1提前了1小时再截断,最终导致日期偏移。
修正后的核心是将DATEDIFF的第二个参数改为0,以此基于基准时间1900-01-01 00:00:00计算小时差,实现正确的小时截断。完整代码如下:
GETDATE() AS date_utc_minus_6, /*system date field*/ date_utc_minus_6 AT TIME ZONE 'Central Standard Time' AT TIME ZONE 'Central European Standard Time' AS date_utc_1, DATEADD(hour, DATEDIFF(hour, 0, date_utc_1), 0) AS field_lower_limit, DATEADD(hour, 1, field_lower_limit) AS field_upper_limit
运行上述代码后,field_lower_limit会正确截断到date_utc_1所在小时的起始时间,field_upper_limit则为下一小时的起始时间,完全符合示例中的预期结果。
内容的提问来源于stack exchange,提问作者ayakuza91

