sql - UTC 时间到本地时区(中部时间)转换 MS SQL Server

标签 sql sql-server function sql-server-2012 timezone

这个问题是对这个 question 的跟进.
我有一个 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

由于我们处于夏令时,我使用 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
...

哪个应该是(中央时间),
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
...

所以,我像这样改变了@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

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

编辑:

看了答案和reference link之后来自#Siyual,我创建了 dbo.TZCalendar表,我试图创建一个这样的函数(接受一个参数并从引用链接返回一个日期)
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

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

最佳答案

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

SELECT YourInputDatetimeInUTC AT TIME ZONE 'UTC' AT TIME ZONE 'Central Standard Time'

第一个断言您的输入是 UTC,第二个将其转换为美国中部时间,包括适用的 DST(使用 Windows 时区标识符)。

但是,既然你说的是 SQL 2012,我会推荐我的 SQL Server Time Zone Support项目,这是一个单一的操作并使用 IANA 标识符:
SELECT Tzdb.UtcToLocal(YourInputDatetimeInUTC, 'America/Chicago')

关于sql - UTC 时间到本地时区(中部时间)转换 MS SQL Server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46451657/

相关文章:

sql - 如何快速检测并解决数据库的SQL Server索引碎片?

python - 使用返回函数中的变量作为另一个函数的参数

sql - 如何安全地释放数据库中 1 个表的未分配空间?

sql - 根据其他列值按查询分组

sql-server - Mac OS X 10.6 ODBC 驱动程序

c++ - 从另一个文件调用一个函数到另一个函数C++

c++ - 为什么 int 不能用作返回类型的左值,而用户定义的类可以?

sql - TSQL 按位非

sql - 如何获取数据库中发生变化的数据?

SQL 将值连接到一组值