【问题标题】:scheduling a job at a logical time (un-effected by daylight savings time)在逻辑时间安排作业(不受夏令时影响)
【发布时间】:2013-02-22 04:05:17
【问题描述】:

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

假设纽约的一位用户将活动安排在美国东部标准时间晚上 8 点进行。无论夏令时如何,我希望该用户在全年每周东部标准时间晚上 8 点发生该事件。

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

人们通常如何解决这类问题?换句话说,我应该如何以最简单的方式在我的数据库中存储一个逻辑时间,正确显示它,使用它来正确调度任务,而不考虑夏令时,对于所有用户时区?

【问题讨论】:

  • 而且,比如说,客户端已经移动到另一个时区,它是否也应该在新时区的晚上 8 点运行?

标签: algorithm timezone


【解决方案1】:

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

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

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

The Microsoft Time Zone Database

专业人士

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

缺点

  • 由 Microsoft 而非标准机构或社区维护。
  • 区域往往非常宽泛而不是精细。
  • 不适合历史时区变化。
  • 与非 Microsoft 服务器的互操作性可能很痛苦。
  • 更新频率较低。

The IANA/Olson Time Zone Database

专业人士

  • 在 Linux、Mac、Java、PHP 和许多其他平台上广泛实施。
  • 库可用于JavaScriptWindows/.Net
  • 以典型城市命名的精致、独特的时区。
  • 包含时区变化的历史数据。
  • 在许多 RFC 和其他标准中被引用。
  • 社区维护,最近得到 IANA 的支持。
  • 经常更新,一年几次。

缺点

  • 通常不会自动维护,尽管某些实现可能会这样做。
  • 有这么多区域,很难为您的用户提供一个简单的下拉列表。良好的用户体验需要基于地图的时区选择器,例如 this one

现在您已经确定了您的用户所在的时区 - 让我们进入您最初问题的核心。在不考虑 DST 更改的情况下,您应该如何处理在同一本地时间的重复事件?

你实际上有两个不同的关注点,持久性和执行。

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

为了执行,您需要在特定的预定时间触发您的重复作业。您的作业正在运行的服务器可能完全位于不同的时区。您需要的是一系列 UTC DateTime 值,因此您可以将任务调度程序设置为在瞬间的特定时刻触发。您也可以为此使用本地时间加UTC偏移量,例如.Net中的DateTimeOffset。这将具有在每个值上看到 8:00PM 的优势,即使偏移量在 -4 和 -5 之间切换。见DateTime vs DateTimeOffset

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

【讨论】:

【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2013-06-29
      • 2013-06-27
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      • 2018-11-02
      • 2021-08-25
      • 1970-01-01
      • 2015-06-23
      相关资源
      最近更新 更多