我想知道其他人如何处理这种情况。
如果你有一份工作计划在凌晨1:30运行,该怎么办? 在秋天,时间变化的时候,一点到一点五十九分五十九分的时间会重演,所以工作会跑两次。
可以是Windows任务计划程序,SQL代理或任何其他计划工具。 大多数这些工具似乎是基于机器时间,而不是UTC时间。 如果我告诉它每天晚上在UTC时间工作,那么我就不会有重复的小时问题。
根据当地时间适当安排未来任务,考虑到时区和夏令时,是一个非常复杂的课题。 我之前从Stack Overflow的编程angular度来写这篇文章。
我将从非编程angular度总结:
根据当地时间定义您的重复模式 – 不是UTC 。 例如,如果您每天早上8:00设置一个闹钟来唤醒您,则不需要在夏令时过渡之后的一个小时之前提前一个小时起床。 如果我在美国太平洋时区,我不能在UTC时间下午4:00进行安排,因为在过渡之后,必须切换到UTC时间下午3:00,以保持当地时间上午8:00。
定义“本地”时间所代表的时区。 不要认为服务器的本地时区是与最终用户相同的时区。
将当地时间投射到您希望事件触发的每个事件的UTCdate和时间。
您几乎总是会为即将发生的下一次操作做好准备,以便您可以使用UTC时钟确定运行的实时时刻。
在某些情况下,您可能还想要投射接下来的几个(或多个)实例,例如接下来的5个实例,或者下一年的所有实例。 (这部分对应用程序的要求非常具体。)
有一个适当的策略(固定或可configuration),以及在夏时制转换时发生的情况:
对于“春季前进”的转型,当地方时间可能不存在的时候,有一个缺失的时期。 例如,在美国太平洋时间,计划在当地时间凌晨2点运行的每日任务将不会在2014年3月9日存在。在大多数情况下,您需要按时间节省时间(通常为1小时),所以在那一天它将在凌晨3点运行,但是在下一个时间将在2点钟运行。 (但是,完全可能的是,您将需要针对此不同的策略。)
对于“倒退”转换,当发生可能存在两次时,重复的本地时间有重叠。 例如,在美国太平洋时间,计划在凌晨1点运行的每日任务将在2014年11月2日运行两次。在大多数情况下,您会希望在第一次运行时运行1次:00 AM PDT,跳过下一次同一date的上午1:00 PST。 (但是,你也许需要一个不同的策略,比如在第二次运行时,或者同时运行。YMMV)
如果您需要更新您的时区数据,请准备重新计算您所有发生的UTC时间。 IANA / Olson TZDB每年都会发布多个更新,因为世界各国政府一直在改变他们的时区偏移和夏令时规则。 在将来任何特定的时间内,你都不能假定规则不会改变 。
请务必订阅时区数据发布的公告 ,并有一个将它们应用于您的系统和/或应用程序的过程。
在传统的企业环境中,这应该是IT运营人员的责任。
根据您的环境,您可能会通过tzdata linux软件包更新,通过Java JRE或tzupdater或其他任何渠道获取这些数据。 有时它是特定于环境的,有时是特定于编程平台的,比如用于PHP的timezonedb PECL包等等。
微软拥有自己的时区数据。 在Windows上,如果您使用.NET中的TimeZoneInfo (例如),则使用此数据。 更新来自这里 ,也通过Windows更新自动推出,所以你应该留意这些,所以你知道什么时候/如果你需要重新计算。
有了这一切的理解,仍然有一个情况,你只需要按UTC排定,这是绝对的未来事件。 例子:
每X小时或每X分钟运行一次的作业
日出开始和停止时间,或其他天文现象。
对时间敏感的安全窗口,例如在预先安排的时间将敏感信息传输给另一方时。
Windows不一定在做正确的事情。 注意你如何定义触发器:

当您选中标有“跨时区同步”的框时,则该任务仅由UTC预定。 (所有时间仍显示为当地时间,但存储为UTC。)所以这是我以前称为“绝对”的事件。
当您不选中该框时,它将使用运行代码的计算机的本地时区。 它不给你任何选项来指定时区,所以这不是一个很好的实施恕我直言。
我不完全确定这是DST的行为,但我会试验并就此回复你。 这可能是我上面描述的,但不一定。
SQL Agent调度程序更糟糕,因为它只允许您使用本地服务器时间。 同样,不能指定时区,也不能指定UTC。
它已被要求 ,但不被接受。
一般来说,不关心。
问问题“如果任务运行两次,怎么办?
一般来说,这并不重要,所以你不需要做任何事情。 如果这很重要,最简单的解决scheme就是将作业从夏时制变化的影响中移出。
正如您所指出的那样,1AM到2AM之间的小时在DST结束时重复; 当发生逆向变化(DST开始)时,2AM和3AM之间的时间不会发生(并且您的工作将不会运行)。 你最好的select将会是