我想知道其他人如何处理这种情况。
如果您有一个计划在凌晨 1:30 运行的作业怎么办。在秋天,当时间改变时,1:00:00 到 1:59:59 的时间会重复,因此该作业会运行两次。
可以是 Windows 任务计划程序、SQL 代理或任何其他计划工具。这些工具中的大多数似乎都基于机器时间,而不是 UTC 时间。如果我告诉它每晚在 UTC 时间运行这项工作,那么我就不会遇到重复时间问题。
我想知道其他人如何处理这种情况。
如果您有一个计划在凌晨 1:30 运行的作业怎么办。在秋天,当时间改变时,1:00:00 到 1:59:59 的时间会重复,因此该作业会运行两次。
可以是 Windows 任务计划程序、SQL 代理或任何其他计划工具。这些工具中的大多数似乎都基于机器时间,而不是 UTC 时间。如果我告诉它每晚在 UTC 时间运行这项工作,那么我就不会遇到重复时间问题。
考虑到时区和夏令时,按当地时间正确安排未来任务是一个非常复杂的主题。我以前从这里和这里的 Stack Overflow 的编程角度写过它。
我将从非编程的角度来总结一下:
按本地时间而不是 UTC定义您的重复模式。例如,如果您将每日闹钟设置为每天早上 8:00 叫醒您,那么您不希望在夏令时转换后提前一小时或晚一小时醒来。如果我在美国太平洋时区,我无法安排 UTC 下午 4:00,因为在转换后它必须切换到下午 3:00 UTC 以保持相同的当地时间上午 8:00。
定义“本地”时间所代表的时区。不要假设服务器的本地时区与对最终用户很重要的时区相同。
将本地时间投影到您希望事件触发的每个事件的 UTC 日期和时间。
您几乎总是会在下一次立即发生时这样做,这样您就可以使用 UTC 时钟来确定运行的真正时刻。
在某些情况下,您可能还希望预测接下来的几个(或许多)实例,例如接下来的 5 次事件,或下一年的所有事件。(这部分与应用程序的要求高度相关。)
制定策略(固定的或可配置的),以应对夏令时转换时发生的事件:
对于“弹簧向前”过渡,当该事件可能不存在时,会缺少本地时间。例如,在美国太平洋时间,计划在当地时间凌晨 2:00 运行的每日任务在 2014 年 3 月 9 日将不存在。在大多数情况下,您需要将该时间提前节省量(通常为 1 小时) ),因此当天它将在凌晨 3:00 运行,但在下一个实例中将恢复为凌晨 2:00 运行。(但是,您完全有可能为此需要不同的策略。)
对于“回退”过渡,当事件可能存在两次时,重复的本地时间会重叠。例如,在美国太平洋时间,计划在凌晨 1:00 运行的每日任务将有两个可能的时间在 2014 年 11 月 2 日运行。在大多数情况下,您希望在第一次出现 1时运行:00 AM PDT 并跳过同一日期的 1:00 AM PST 的下一次出现。(但同样,您可能需要不同的策略,例如在第二次出现时运行,或者同时运行。YMMV)
如果您需要更新时区数据,请准备好重新计算所有出现的 UTC 时间。IANA/Olson TZDB每年都会发布多次更新,因为世界各国政府一直在改变他们对时区偏移和夏令时规则的看法。 您不能假设未来任何特定的时间段内规则都不会改变。
请务必订阅时区数据发布公告,并制定将其应用到您的系统和/或应用程序的流程。
在传统的公司环境中,这应该是 IT 运营人员的责任。
根据您的环境,您可能通过
tzdata
linux 包更新、Java JRE 或 tzupdater或任何数量的其他渠道获取此数据。有时它是特定于环境的,有时是特定于编程平台的,例如PHP 的 timezonedb PECL 包等等。微软有自己的时区数据。在 Windows 上,如果您使用
TimeZoneInfo
的是 .NET(例如),则您正在使用此数据。更新来自这里,并且也会通过 Windows 更新自动推出,因此您应该留意这些更新,以便知道何时/是否需要重新计算。了解了所有这些之后,仍有一种情况是您可以仅按 UTC 进行安排,那就是绝对未来事件。例子:
每 X 小时或每 X 分钟运行一次的作业。
日出开始和停止时间,或其他天文现象。
时间敏感的安全窗口,例如在预定时间将敏感信息传输给另一方时。
Windows 任务计划程序
Windows 不一定做正确的事。注意你如何定义触发器:
当您选中标有“跨时区同步”的框时,该任务仅由 UTC 安排。(所有时间仍显示为本地时间,但存储为 UTC。)所以这是我之前所说的“绝对”事件。
当您未选中该框时,它将使用运行代码的计算机的本地时区。它没有为您提供任何指定时区的选项,因此恕我直言,这不是一个很好的实现。
我不确定它的 DST 行为,但我会进行试验并就此与您联系。它可能会做我上面描述的事情,但不一定。
SQL 代理
SQL 代理调度程序更糟糕,因为它只允许您使用本地服务器时间。同样,不能指定时区,也不能指定 UTC。
它已被请求,但未被接受。
一般来说,不关心。
问一个问题“如果任务运行两次怎么办?”
一般来说,这并不重要,所以你不需要做任何事情。如果这很重要,最简单的解决方案是将工作移出受夏令时更改影响的时间。
正如您所指出的,凌晨 1 点到凌晨 2 点之间的时间在 DST 结束时重复;当发生反向变化时(夏令时开始),凌晨 2 点到凌晨 3 点之间的时间不会发生(并且您的工作不会运行)。你最好的选择将是