我试图在本地时间显示datetime值。默认情况下,Azure SQL数据库以UTC存储日期和时间,这是没有办法的。(从本地SQL Server迁移时,这是一个痛苦的过程。)我想用中欧时间显示存储的时间值。
现在当地时间是11:30 (CET)。UTC时间为10:30。
DECLARE @TestTime DATETIME;
SET @TestTime = '2016-11-02 10:30:00'
SELECT @TestTime
--Returns 2016-11-02 10:30:00
SELECT @TestTime AT TIME ZONE 'Central European Standard Time'
--Returns 02 November 2016 10:30:00 +01:00
我需要返回2016-11-02 11:30:00。现在进入有趣的部分:
正如这里所建议的:
SELECT convert(DATETIME,@TestTime AT TIME ZONE 'Central European Standard Time',1)
--Returns 2016-11-02 09:30:00 So instead of adding the timezonedifference it subtracts it.
这个有效,但是让我恶心:
SELECT DATEADD(MINUTE,DATEPART(tz,@TestTime AT TIME ZONE 'Central European Standard Time'),@TestTime)
--Returns 2016-11-02 11:30:00
这里也提出了类似的解决方案,但它使用的是字符串操作。我的怀疑是什么是错误的在AT时区;它应该显示11:30 +1,而不是10:30 +1,不是吗?
真的没有合适的方法来显示UTC时间在当地时间吗?这种"绕过它"的做法让人感觉非常肮脏,尤其是在任何时候它都可能停止工作(例如微软修复/引入了一个bug)。
谢谢!
AT TIME ZONE
语句执行两个不同的操作:
-
To 断言
datetime
(或datetime2
)在特定时区,因此查找该区域的正确偏移量并返回应用正确偏移量的datetimeoffset
值 -
To 转换一个
datetimeoffset
值到一个不同的时区,使用源值的偏移量来确定一个确切的时间点,然后查找请求时区的新偏移量并应用它。这将返回一个datetimeoffset
,其本地时间和偏移量可能与原始时间不同,但表示相同的时刻。
您只使用了第一部分。要将datetime
从UTC转换为特定的时区,您需要同时使用。
SELECT @TestTime AT TIME ZONE 'UTC' AT TIME ZONE 'Central European Standard Time'
第一个AT TIME ZONE
断言输入的datetime
是UTC,导致datetimeoffset
的偏移量为+00:00
。第二个AT TIME ZONE
将其转换为所请求的时区。