Getting a local date/time for a specific timezone in SQL Server
使用SQL Server 2008+。sqlcr不是选项。
我有一种情况,所有数据都存储在UTC中。我需要通过确定某个特定的当地时间,比如说上午8点,用UTC来比较这些数据。本地时间的时区将逐行变化。(存储了每行的时区,所以这不是问题。)某些本地时间没有与之相关的日期。总是"早上8点"。
我在数据库中有时区数据,如果时区遵循夏令时,这也会告诉我基本的UTC偏移量。
但现在我有点困了。
我的问题是,为了进行夏令时调整,我需要知道特定时区中的当前日期/时间是否在某些范围内,但我只能转换到适当的本地时间来进行检查,如果我知道是否是夏令时!换言之,除非我知道UTC偏移是否由于日光节约而关闭,否则如何检查是否为日光节约?
这是鸡和蛋的问题。
在我看来,唯一的解决方案是能够有一个表来计算每个时区的夏令时感知补偿。
思想?
你确实有一个模棱两可的问题,但这不是鸡和蛋的问题。好的。
你缺少的信息是,"什么定义了一天?"我知道,听起来很疯狂,但是"一天"不是一个普遍的概念。这是本地的。好的。
只需一分钟,就可以将时区、DST和UTC的问题放在一边。如果我问你,"现在8点以外我们还有多少小时?"你可以给我两个不同的答案。现在是晚上7点,所以你可能会说"11个小时",因为这就是我们今天早上8点的时间。但我也可以说"13小时"——因为这就是我们明天早上8点开始的时间。现在在这个非常简单的示例中,您可以用两种不同的方法之一消除歧义。你可以说"最后8点"或"下一个8点"。或者你可以说"不管今天发生了什么。"好的。
现在回到UTC的概念。什么是"UTC日"?嗯,我们知道现在是24小时,因为UTC不遵循任何夏令时。但是说它运行"从午夜到午夜UTC",并不是一个非常有意义的度量。当然,也有一些地方使用这个定义(例如,stackoverflow的stats引擎)。但对大多数人来说,我们在当地时间想到"今天"。好的。
所以我不能说"今天早上8点左右"。唯一的日期度量是UTC日期。你不知道该看哪一个当地的日期。让我们举一个真正的例子:好的。
- 我住在亚利桑那州的凤凰城,所以我的时区偏移是UTC-7。我们这里没有DST。
- 目前是2013年6月14日当地时间下午7点。
- 现在是2013年6月15日凌晨2点。
现在我把时间记录在数据库中,然后我问:好的。
- "我们离亚利桑那时间早上8点有多远?"
- 根据我掌握的信息,我不知道我应该在6月14日上午8点还是6月15日上午8点寻找。只有后者属于同一个UTC日期,但我肯定对其中任何一个都感兴趣。
如果您可以在业务逻辑中决定最后一次还是下一次,那么您可以解决这个问题。只需将UTC日期时间转换为本地时区。然后向前或向后滚动到所需时间。如果您的时区有DST,并且您一路上跨越了一个过渡日期,那么您可以对此进行调整。好的。
您也可以选择这两个时间中最近的一个,但当然这都取决于您的业务逻辑。好的。
另一种方法是利用您正在比较的UTC时间来确定您今天在哪个本地。所以在我上面的例子中,亚利桑那州当地的6月14日从6月13日17:00 UTC运行到6月14日17:00 UTC。好的。
总而言之,您想知道"在这个UTC日期时间周围的DST中是上午8点吗?"如果没有更多的信息,你不能回答这个问题,要么是上午8点的日期,要么是一些逻辑关系,其中有几个选项可用。选择一个适合你需要的策略。好的。
更新好的。
你在评论中问过:好的。
How can I know if right now in UTC is in dst in X time zone so I can adjust accordingly?
Ok.
这是
所以,让我们假装我住在纽约市。查看此站点,我们知道EDT于2013年3月10日当地时间凌晨2点生效,将于2013年11月3日当地时间凌晨2点返回EST。好的。
所以我们有以下内容:好的。
1 2 3 4 5 6 7 8 9 10 | UTC Local datetimeofffset 2013-03-10T05:00:00Z 2013-03-10T00:00:00-05:00 2013-03-10T06:00:00Z 2013-03-10T01:00:00-05:00 2013-03-10T07:00:00Z 2013-03-10T03:00:00-04:00 <--- transition 2013-03-10T08:00:00Z 2013-03-10T04:00:00-04:00 ... 2013-11-03T04:00:00Z 2013-11-03T00:00:00-04:00 2013-11-03T05:00:00Z 2013-11-03T01:00:00-04:00 2013-11-03T06:00:00Z 2013-11-03T01:00:00-05:00 <--- transition 2013-11-03T07:00:00Z 2013-11-03T02:00:00-05:00 |
现在注意,如果去掉偏移量,就只有一个单向函数。换言之,您始终可以为UTC时间确定正确的本地时间,但除非您知道回退过渡期间的偏移量(或者除非您愿意接受模糊性),否则无法转到另一个方向。好的。
所以从UTC到当地时间的算法应该是这样的:好的。
- 在这种情况下,日光偏移是有效的。
- 您的时区数据应该包含此信息。
- 如果没有,那么您需要重新考虑时区表的来源。
让我们用另一个1:30的时间再试一次:好的。
- 在这种情况下,标准偏移量是有效的。
- 我们怎么知道?因为-4是日光偏移,DST应该在当地时间2:00结束。我们有2:30的本地时间与该偏移相关,因此只有标准时间在此时区有效。
那么你能把UTC转换成本地的吗?对。总是。好的。
但您也说过,另一列中的本地值类似于
有时,您可能只想选择其中一个,但有时您可能想出错。有时你可能想让你的用户选择他们感兴趣的两个。看到下面这样的对话并非闻所未闻:好的。
1 2 3 4 5 | DAYLIGHT SAVING TIME We're sorry, but there are two different instances of 1:30 AM on this day. Which did you mean? [1:30 AM Eastern Daylight Time] [1:30 AM Eastern Standard Time] |
…如果你不知道,那是按钮。:)好的。好啊。