我正在尝试以当地时间显示日期时间值。默认情况下,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。现在为了有趣的部分:
按照建议here:
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
已提出类似的解决方案here,但它使用字符串操作。我怀疑AT TIME ZONE出了什么问题;它应该显示11:30 +1,而不是10:30 +1,不是吗?
是否真的没有正确的方法在当地时间显示UTC时间?这种“黑客攻击”感觉非常脏,特别是因为在任何时候它都可能停止工作(例如微软修复/引入了一个错误)。
谢谢!
答案 0 :(得分:4)
AT TIME ZONE
语句执行两个不同的操作:
断言 datetime
(或datetime2
)处于特定时区,从而查找正确的偏移量对于该区域并返回datetimeoffset
值并应用正确的偏移量。
将 一个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
将其转换为请求的时区。