Azure SQL显示本地时间

时间:2016-11-02 11:51:27

标签: sql-server tsql timezone azure-sql-database

我正在尝试以当地时间显示日期时间值。默认情况下,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时间?这种“黑客攻击”感觉非常脏,特别是因为在任何时候它都可能停止工作(例如微软修复/引入了一个错误)。

谢谢!

1 个答案:

答案 0 :(得分:4)

AT TIME ZONE语句执行两个不同的操作:

  1. 断言 datetime(或datetime2)处于特定时区,从而查找正确的偏移量对于该区域并返回datetimeoffset值并应用正确的偏移量。

  2. 一个datetimeoffset值转换为其他时区,使用源值的偏移量确定准确的时间点,然后查找所请求时区的新偏移量并应用它。这将返回一个datetimeoffset,其本地时间和偏移量可能与原始时间不同,但代表的是同一时刻。

  3. 您仅使用第一部分。要将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将其转换为请求的时区。