使用SQL Server 2016或更新,我想将代表UTC值的DateTime转换为服务器上的本地时间。
我想在时区使用,但它假设您明确知道服务器的时区是什么。我们的产品可以安装在世界各地的任何地方,所以我不能假设时区。
有没有办法(不使用CLR或类似(来获取服务器时区的名称,以便我可以在时区调用中使用它?
或SQL 2016中有其他方法可以从UTC转换为local?
-- how do set a value for @TZ that has the server's time zone name
DECLARE @TZ NVARCHAR(100) = 'Server Time Zone'
DECLARE @D DATETIMEOFFSET = '2017-01-01T00:00:00+00:00'
SELECT @D AT TIME ZONE @Tz
您可以使用getDate((和getutcdate((分钟的日期差来确定您与UTC的差异,并将其应用于新的时间戳。Sqlauthority还提供了一种为您的服务器获取时区的好方法。
DECLARE @TimeZone VARCHAR(50)
EXEC MASTER.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
'SYSTEMCurrentControlSetControlTimeZoneInformation',
'TimeZoneKeyName',@TimeZone OUT
SELECT @TimeZone
在实际的项目应用程序中没有尝试过此功能,但希望这会有所帮助。
DATENAME(TZOFFSET , SYSDATETIMEOFFSET())
这应该为您提供服务器时间偏移,然后尝试查询在时区使用的匹配时区名称。它可能可以返回多个匹配的时区名称,但是只要它具有相同的偏移以进行准确的转换,我们只需要一个。
下面的示例脚本:
DECLARE @TimeZoneName NVARCHAR(100);
SELECT TOP 1 @TimeZoneName = name FROM sys.time_zone_info WHERE current_utc_offset = DATENAME(TZOFFSET , SYSDATETIMEOFFSET())
SELECT GETUTCDATE() AT TIME ZONE @TimeZoneName;
看来,在不依赖CLR或XP_Regread的情况下,似乎无法在SQL 2016中执行此操作,由于我希望SQL用户能够以下事实,我都不要这样做具有最小的许可。
最后,决定创建一个将返回服务器时区的UDF。
创造性的部分是,UDF是动态创建的,并且使用XP_Regread在UDF 创建时间中使用XP_Regread读取服务器的时区,此后,该时区实质上是对UDF进行了硬编码的。。
我假设用户有创建UDF的权限,他们也可能有权调用XP_Regread。创建后,不需要特殊的权限。