UTC时间到本地时区(中央时间)的转换MS SQL Sever

3 sql sql-server timezone function sql-server-2012

这个问题是这样的跟进问题。我有一个UTC时间列,我想转换为当前本地时间(Central Time Zone or America/Chicago)。我试图使用@Ron Smith的答案中的[dbo].[fn_UTC_to_DST]函数,即函数。

在该函数中,它需要两个参数,例如UTC时间和偏移量。我都这样输入

SELECT  dbo.fn_UTC_to_DST([time(UTC)],5) as Date
FROM tbl
Run Code Online (Sandbox Code Playgroud)

由于我们处于夏令时,因此我使用5作为偏移量。我的输出看起来像这样,

2017-09-27 20:55:00.000
2017-09-27 20:56:00.000
2017-09-27 20:57:00.000
2017-09-27 20:58:00.000
...
Run Code Online (Sandbox Code Playgroud)

应该是(中央时间),

2017-09-27 09:55:00.000
2017-09-27 09:56:00.000
2017-09-27 09:57:00.000
2017-09-27 09:58:00.000
...
Run Code Online (Sandbox Code Playgroud)

因此,我这样更改了@Ron Smith的功能,

CREATE FUNCTION [dbo].[fn_UTC_to_DST]
(
    @UTC datetime,
    @StandardOffset int
)
RETURNS datetime
AS
BEGIN
declare 
    @DST datetime,
    @SSM datetime, -- Second Sunday in March
    @FSN datetime  -- First Sunday in November

-- get DST Range
set @SSM = datename(year,@UTC) + '0314' 
set @SSM = dateadd(hour,-5,dateadd(day,datepart(dw,@SSM)*-1+1,@SSM))  -- Changed from 2 to -5
set @FSN = datename(year,@UTC) + '1107'
set @FSN = dateadd(second,-6,dateadd(hour,2,dateadd(day,datepart(dw,@FSN)*-1+1,@FSN)))  -- changed from 1 to -6 

-- add an hour to @StandardOffset if @UTC is in DST range
if @UTC between @SSM and @FSN
    set @StandardOffset = @StandardOffset + 1

-- convert to DST
set @DST = dateadd(hour,@StandardOffset,@UTC)

-- return converted datetime
return @DST

END

GO
Run Code Online (Sandbox Code Playgroud)

但是,这仍然给我与上面相同的结果。1.我在中部时间应该更改什么?2.是否可以在夏令时自动更改为-5,在标准时间自动更改为-6?

编辑:

在查看了#Siyual 的Answer和参考链接之后,我创建了dbo.TZCalendar表,并尝试创建这样的函数(采用一个参数,并从Refreence链接返回日期)

CREATE FUNCTION dbo.ConvertUTCToLocal
(
  @utc DATETIME
)
RETURNS Datetime
AS BEGIN 
  SELECT UTCToLocal = DATEADD(HOUR, CASE 

  -- within Daylight Savings Time
  WHEN @utc >= UTC_DST_Start AND @utc < UTC_DST_End 
  THEN -5 

  -- within Standard Time
  ELSE -6 END, @utc)

FROM dbo.TZCalendar 
WHERE CONVERT(DATE,@utc) >= [Year] 
  AND CONVERT(DATE,@utc) < DATEADD(YEAR, 1, [Year])
END
GO
Run Code Online (Sandbox Code Playgroud)

这是行不通的。该逻辑对我来说似乎是正确的,但是,我只需要一个没有函数SCHEMABINDING(在参考链接中完成)。我怎样才能做到这一点?

Mat*_*int 5

如果您使用的是SQL Server 2016+(或Azure SQL数据库),则内置此功能:

SELECT YourInputDatetimeInUTC AT TIME ZONE 'UTC' AT TIME ZONE 'Central Standard Time'
Run Code Online (Sandbox Code Playgroud)

第一个断言您的输入是UTC,第二个断言将您输入为UTC,包括适用的DST(使用Windows时区标识符)。

但是,由于您说的是SQL 2012,因此我建议使用SQL Server时区支持项目,该项目是单个操作,并且使用IANA标识符:

SELECT Tzdb.UtcToLocal(YourInputDatetimeInUTC, 'America/Chicago')
Run Code Online (Sandbox Code Playgroud)