T-SQL中使用AT TIME ZONE转换时区后无法存入变量的问题
SQL datetime时区转换:解决AT TIME ZONE赋值后值不变的问题
当你使用AT TIME ZONE转换时区后直接赋值给datetime变量时,值不变的核心原因是:AT TIME ZONE返回的是datetimeoffset类型(带时区偏移的时间),而datetime类型本身不存储时区信息,隐式转换时会自动丢弃偏移量,将时间转回原时区的本地时间。
解决方案:两种可行方法
方法1:链式使用AT TIME ZONE + 显式转换
利用AT TIME ZONE的链式转换,先将原datetime转为目标时区的datetimeoffset,再显式转换为datetime,这样就能保留转换后的时间值:
DECLARE @OriginalDT DATETIME = '2024-05-20 12:00:00'; DECLARE @TargetDT DATETIME; -- 示例:将原时间(视为UTC)转换为中国标准时间的datetime SET @TargetDT = CAST( @OriginalDT AT TIME ZONE 'UTC' AT TIME ZONE 'China Standard Time' AS DATETIME);
这里的逻辑是:
- 第一个
AT TIME ZONE 'UTC':将原datetime标记为UTC时区的datetimeoffset - 第二个
AT TIME ZONE 'China Standard Time':将UTC的datetimeoffset转换为目标时区的datetimeoffset - 最后
CAST(... AS DATETIME):提取目标时区的本地时间值存入datetime变量
方法2:手动计算偏移量(dateadd+datediff)
这就是你提到的技巧,通过计算目标时区与原时区的偏移秒数,手动调整时间:
DECLARE @OriginalDT DATETIME = '2024-05-20 12:00:00'; DECLARE @TargetDT DATETIME; -- 计算偏移秒数并调整时间 SET @TargetDT = DATEADD( SECOND, DATEDIFF( SECOND, @OriginalDT AT TIME ZONE 'UTC', @OriginalDT AT TIME ZONE 'UTC' AT TIME ZONE 'China Standard Time' ), @OriginalDT );
注意事项
datetime类型仅存储本地时间值,不带任何时区标识。无论用哪种方法,最终存入变量的都是目标时区的本地时间数值,而非带时区的时间对象。如果需要保留时区信息,建议改用datetimeoffset类型存储。
内容的提问来源于stack exchange,提问作者VladimirK
相关产品推荐
相关产品推荐

