在逻辑时间安排工作(不受夏令时影响)

时间:2013-03-07 04:22:22

标签: algorithm timezone

这不是关于技术本身的帖子,而是关于适当算法的帖子。我希望我的用户能够安排我的应用程序上的事件发生在每个特定时间(他们将在我的网站上的时区中显示)。

假设纽约的用户安排该事件发生在美国东部时间晚上8点。无论夏令时如何,我希望这个用户每周美国东部时间每周晚上8点开始活动。

目前我将UTC中的时间值存储在我的数据库中,但UTC不会根据一年中的时间进行更改。似乎有些时区确实有夏令时的概念,有些时候也没有,这意味着如果我要动态进行任何时区翻译处理(在任何查询日期以便安排事件或显示的查询之前)网站上的预定时间)我必须看看用户的时区是否支持夏令时以及目标时间戳是否属于夏令时。

人们通常如何解决此类问题?换句话说,我应该如何在我的数据库中存储逻辑时间,正确显示它,使用它以最简单的方式为所有用户时区正确地安排任务而不管夏令时?

3 个答案:

答案 0 :(得分:1)

我会做出一个假设,你的意思是“......在东部时间每周一整年”。当您说EST时,您具体指的是东方标准时间。当DST适用时,它被称为东方日光时间(EDT)。

此外,缩写不是识别时区的好方法。我怎么知道你在美国的EST(UTC-5)而不是澳大利亚的EST(UTC + 10)?缩略语含糊不清。您可以看到相当全面的列表here

首先要做的是决定如何识别用户的时区。有两个常用的数据库:

<强> The Microsoft Time Zone Database

<强>赞成

  • 内置于Windows操作系统。
  • 通过Windows Update自动部署更新。
  • 易于使用Win32或.Net Framework。

<强> CON外

  • 由Microsoft而非标准组织或社区维护。
  • 区域往往非常宽阔而不是精致。
  • 历史时区变化不佳。
  • 与非Microsoft服务器的互操作性可能很痛苦。
  • 不太频繁更新。

<强> The IANA/Olson Time Zone Database

<强>赞成

  • 广泛应用于Linux,Mac,Java,PHP和许多其他平台。
  • 图书馆适用于JavaScriptWindows/.Net
  • 从示例城市命名的精致独特时区。
  • 包含时区更改的历史数据。
  • 在许多RFC和其他标准中引用。
  • 社区维护,最近由IANA支持。
  • 经常更新,一年几次。

<强> CON外

  • 通常不会自动维护,但某些实现可能会这样做。
  • 区域太多,可能很难向用户显示简单的下拉列表。基于地图的时区选择器(例如this one)是获得良好用户体验所必需的。

现在您已经确定了您的用户所在的时区 - 让我们了解原始问题的核心。您应该如何处理当地时间的重复事件,而不考虑DST更改?

你实际上有两个不同的问题,持久性和执行。

对于持久性(以及传输,显示等),您需要存储组合的本地时间和时区。例如,America/New_York IANA区域的晚上8:00。如果可能在您的框架中,请存储此时间而不使用日期组件。请勿将其转换为UTC或尝试将其调整为夏令时。您只是以他们向您表达的方式捕获用户意图。

执行时,您需要在特定的预定时间解雇定期作业。您的作业运行的服务器可能完全位于不同的时区。您需要的是一系列UTC DateTime值,因此您可以将任务计划程序设置为在瞬时特定时刻触发。您也可以使用local-time-plus-utc-offset,例如.Net中的DateTimeOffset。即使偏移量在-4和-5之间切换,这也有利于在每个值上看到晚上8点。请参阅DateTime vs DateTimeOffset

要对齐这两个概念,您需要一些代码来评估本地时间并计算执行时间戳。您可以在每个作业运行时设置下一个计划作业,或者您可以定期执行此操作并为未来的X个事件计划事件时间。随你(由你决定。如果您需要将未来的事件日期放在日历上 - 那么您当然需要采用后一种方法。

答案 1 :(得分:0)

也许您可以使用任何公开的时区API。例如。 https://developers.google.com/maps/documentation/timezone/

答案 2 :(得分:0)

我会尽快转换为UTC并尽可能晚地转换为UTC,因为当夏季结束时国家/地区退出夏令时时他们会把时钟放回去,并且当天有两个小时同一时间 - 所以DST时间不能唯一描述所有时间。