Joh*_*ohn 8 sql-server timezone
我试图在SQL Server 2016和Azure SQL中使用新的AT TIME ZONE语法.我只想把目前在伦敦的时间作为datetime
夏令时进行调整.在运行以下所有命令时,伦敦的时间是凌晨3点27分.
第一步是获得一个datetimeoffset
,我可以成功地做到如下:
DECLARE @dto datetimeoffset
SET @dto = (SELECT GETUTCDATE() AT TIME ZONE 'GMT Standard Time')
SELECT @dto
Run Code Online (Sandbox Code Playgroud)
这会返回一个我期望的值:
2016-04-04 02:27:54.0200000 +01:00
Run Code Online (Sandbox Code Playgroud)
接下来,我想将其转换为a datetime
,这是我的应用程序所期望的.我尝试了三种不同的方法,其中没有一种方法可以提供我正在寻找的结果:
SELECT SWITCHOFFSET(@dto,'+00:00')
-- Returns 2016-04-04 01:27:54.0200000 +00:00
SELECT CONVERT(datetime, @dto)
-- Returns 2016-04-04 02:27:54.020
SELECT CONVERT(datetime2, @dto)
-- Returns 2016-04-04 02:27:54.0200000
Run Code Online (Sandbox Code Playgroud)
我觉得我错过了一些明显的东西 - 是否有一种简单的方法来获取datetimeoffset
并返回该偏移处的日期/时间部分?
Mat*_*int 25
代码的第一行包含错误:
SELECT GETUTCDATE() AT TIME ZONE 'GMT Standard Time'
Run Code Online (Sandbox Code Playgroud)
GETUTCDATE()
返回a datetime
,没有时区偏移信息.因此,如MSDN文档中所述:
如果提供inputdate而没有偏移信息,则该函数应用时区的偏移量,假设在目标时区中提供inputdate值.
因此,即使您检索了UTC时间,您也错误地断言该值是在伦敦时间(对于此日期的夏令时,这是UTC + 1).
处理此问题的最简单方法是将UTC时间作为datetimeoffset
开始时间.
SELECT SYSDATETIMEOFFSET() AT TIME ZONE 'GMT Standard Time'
Run Code Online (Sandbox Code Playgroud)
这会调用转换功能AT TIME ZONE
,在文档中说明:
如果inputdate作为datetimeoffset值提供,则
AT TIME ZONE
子句使用时区转换规则将其转换为目标时区.
考虑一下,如果您的数据实际上来自datetime
某个地方的某个字段,您可能需要使用该功能的两个部分,如下所示:
SELECT mydatetimefield AT TIME ZONE 'UTC' AT TIME ZONE 'GMT Standard Time'
Run Code Online (Sandbox Code Playgroud)
AT TIME ZONE
断言该值的第一个调用是UTC,给datetimeoffset
第二个调用,将其转换为伦敦时间.
任何这些的输出都是a datetimeoffset
,您可以将其转换为或转换为原始问题中显示的datetime
或datetime2
完全相同的输出.(不要switchoffset
用于此.)
此外,伦敦的Windows时区标识符始终是"GMT Standard Time"
.它包括格林威治标准时间和英国夏令时,它们之间有适当的过渡.不要尝试将其更改为"GMT Daylight Time"
- 该标识符不存在.时区标记wiki中也包含在Windows时区的部分中.
小智 5
由于我无法在其他任何地方找到这个,我想我会分享。您可以通过将 datepart (tz) 与 AT TIME ZONE 结合使用来获得以分钟为单位的偏移量。
datepart(tz,UTC_Date AT TIME ZONE 'Central Standard Time')
select dateadd(MINUTE,datepart(tz,cast('2018-07-02 17:54:41.537' as datetime) AT Time Zone 'Central Standard Time'),'2018-07-02 17:54:41.537') as CentralTime
Run Code Online (Sandbox Code Playgroud)
返回
CentralTime
2018-07-02 12:54:41.537
Run Code Online (Sandbox Code Playgroud)