Sql 夏令时和UTC时间

Sql 夏令时和UTC时间,sql,sql-server,tsql,dst,Sql,Sql Server,Tsql,Dst,我们使用一个以UTC时间保存时间戳的程序。我们是犹他州的一家本地公司,因此受到夏令时的影响 例如,如果我们现在接到一个电话,它是12:52:00MST,它将作为19:52:00保存在数据库中 我首先关心的是明年DST将于2016年3月13日再次启动,我将在同一时间运行。UTC的时间戳是18:52:00还是保持在19:52:00 我的第二个担忧是,如果我将数据库中的日期转换为本地时间,那么我必须首先检查它是否为DST,然后检查它是否需要时间-6,如果不是,它将是-7 因此,使用上述示例: IsDS

我们使用一个以UTC时间保存时间戳的程序。我们是犹他州的一家本地公司,因此受到夏令时的影响

例如,如果我们现在接到一个电话,它是
12:52:00
MST,它将作为
19:52:00
保存在数据库中

我首先关心的是明年DST将于2016年3月13日再次启动,我将在同一时间运行。UTC的时间戳是
18:52:00
还是保持在
19:52:00

我的第二个担忧是,如果我将数据库中的日期转换为本地时间,那么我必须首先检查它是否为DST,然后检查它是否需要时间-6,如果不是,它将是-7

因此,使用上述示例:

IsDST = 01:52:00 (-6)
IsNotDST = 12:52:00 (-7)
我想这是我需要担心的事情,因为我必须转换为UTC或从UTC转换

除了上述两个问题之外,我的主要问题是。SQL Server/T-SQL中是否内置了任何东西来为我处理此转换,或者我是否需要自己编写所有东西来满足需要

我已经开始了,但如果有必要,现在需要在DST中工作

DECLARE @declared_start_datetime DATETIME, 
        @declared_end_datetime DATETIME, 
        @converted_start_datetime DATETIME, 
        @converted_end_datetime DATETIME

SET @declared_start_datetime = '11/04/2015 07:00:00' -- Hour we open phones
SET @declared_end_datetime = '11/04/2015 18:00:00' -- Hour we close phones
SET @converted_start_datetime = DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), @declared_start_datetime)
SET @converted_end_datetime = DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), @declared_end_datetime)

select @declared_start_datetime as 'Declared Start', 
       @declared_end_datetime as 'Declared End'
select @converted_start_datetime as 'Converted Start',
       @converted_end_datetime as 'Converted End'
例如,如果我们现在接到一个电话,它是
12:52:00
MST,它将作为
19:52:00
保存在数据库中

我首先关心的是明年DST将于2016年3月13日再次启动,我将在同一时间运行。UTC的时间戳是
18:52:00
还是保持在
19:52:00

山区标准时间为UTC-7,美国山区昼时为UTC-6。如果您写出转换涉及的完整日期、时间和偏移量,就更容易进行推理。此处为标准ISO8601扩展格式:

2015-11-06T12:52:00-07:00=2015-11-06T19:52:00Z
2016-03-13T12:52:00-06:00=2016-03-13T18:52:00Z
方程式左侧的每个局部时间都标有正确的局部时间和该时间的局部偏移量。然后要到达UTC(由
Z
标识),只需从本地时间减去偏移量即可。或者,如果更容易合理化的话,可以将其视为颠倒符号并添加

因此,是的,当您在白天时,它会将其存储在UTC时间
18:52:00
。这是正确的行为

我的第二个担忧是,如果我将数据库中的日期转换为本地时间,那么我必须首先检查它是否为DST,然后检查它是否需要时间-6,如果不是,它将是-7

是的,但请记住,它是您转换的时间戳所反映的日期和时间。无论您当前是否在DST中,这都没有区别

但是,请记住,如果大家都能帮助的话,通常应该避免在数据库层进行时区转换。在绝大多数用例中,这是一个应用层问题

例如,如果您正在从.NET内置的应用程序写入SQL Server,则可以使用
TimeZoneInfo
类和
“Mountain Standard Time”
ID(用于MST和MDT)。或者,您可以使用标识符为
“America/Denver”
的库

通过使用一个图书馆,你不必关心DST何时开始和停止的所有细节,也不必关心它在世界不同地区的历史中是如何变化的

在更罕见的情况下,您实际上需要在数据库级别进行时区转换,您当然可以编写自己的存储过程或UDF(例如链接到的一些问题注释),但根据您的需要,它们可能不够。通常,它们倾向于只编码一组固定的时区转换规则,因此它们不会考虑其他时区或历史变化

SQL Server有几种通用的时区解决方案,但与其他数据库平台不同,它没有内置任何解决方案。我会推荐我的OSS项目,如果你搜索,还有其他项目。但实际上,您应该希望不需要这样做,并且应该尽可能在应用程序层中进行转换


更新:对于SQL Server 2016 CTP 3.1,现在通过语句内置了对时区的支持。看。

你的问题一点也不清楚。你似乎知道
GETUTCDATE()
,你说你想使用UTC时间戳(很好的选择),为什么还要处理本地时间戳?哪个时间是完全相同的时间:
12:52:00
MST还是MDT?这里有一个重要的区别,需要注意夏令时是如何在不同的时间开始的,不久之前就发生了这种转变。这些报告将由公司中的其他人员运行,他们将选择运行报告的时间(当地时间)。我为他们不得不自己学习/转换UTC而产生的大量抱怨/反弹埋下了伏笔。因此,我需要获取他们的本地时间,并将其转换为UTC,以便从数据库中获取正确的记录@amit@JBKing现在正确的时间是明年3月13日凌晨2:00的MST(-7),如果我的研究是正确的,它将变成MDT(-6)。您讲述的“用户故事”是演示层或业务层的问题,而不是数据库/存储层的问题。在那边处理,谢谢马特。不幸的是,我没有使用应用程序,因此需要以这种方式编写DST转换内容。我获取他们提供的日期,检查它是否在DST中,然后将日期更改为6或7,然后使用它从数据库中获取值。这是一个自定义报告请求。我将查看您提到的时区支持项目。请记住一天中的过渡时间,并且在秋季,过渡期的值可能是不明确的。例如,
2015-11-01T01:30
可能是
2015-11-01T01:30-06:00
2015-11-01T01:30-07:00
。你需要决定选择哪一个。如果有疑问,大多数情况下需要第一次(日光)出现。虽然有时是