SQL Server 2016+:如何获取服务器时区并通过AT TIME ZONE转UTC为本地时间
解决SQL Server 2016+中UTC转服务器本地时间的问题
我来给你梳理两种靠谱的解决办法,都是纯T-SQL实现,不用CLR那些复杂的东西:
方法一:动态获取服务器时区名称,配合AT TIME ZONE使用
SQL Server 2016及以上版本自带了sys.time_zone_info系统视图,它直接读取服务器操作系统的时区信息,其中的name字段就是我们需要的时区名称(比如Pacific Standard Time或者China Standard Time)。
你可以先获取这个时区名称,再动态拼接转换语句:
-- 先获取服务器当前时区名称 DECLARE @ServerTimeZone NVARCHAR(100); SELECT @ServerTimeZone = name FROM sys.time_zone_info WHERE current_utc_offset = SYSDATETIMEOFFSET() AT TIME ZONE 'UTC'; -- 转换UTC时间为服务器本地时间 SELECT YourUTCDateTimeColumn AT TIME ZONE 'UTC' AT TIME ZONE @ServerTimeZone AS ServerLocalTime FROM YourTable;
这里的逻辑是:SYSDATETIMEOFFSET()返回服务器本地时间带UTC偏移,把它转成UTC时间后的偏移就是服务器当前的UTC偏移,和sys.time_zone_info里的current_utc_offset匹配,就能准确拿到当前生效的时区名称(包括夏令时切换后的时区)。
方法二:无需时区名称的传统转换方式
如果不想用AT TIME ZONE,也可以通过计算服务器本地时间和UTC时间的偏移量来转换:
SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), YourUTCDateTimeColumn) AS ServerLocalTime FROM YourTable;
这个方法的原理是:DATEDIFF(mi, GETUTCDATE(), GETDATE())会算出服务器本地时间和UTC时间的分钟差(自动适配夏令时变化),然后把这个差值加到你的UTC时间上,就得到了服务器本地时间。不过要注意,这个方法返回的是datetime类型,如果需要带偏移的datetimeoffset,可以再做转换。
内容的提问来源于stack exchange,提问作者Red Puffle




