如何避免夏令时 (DST) 时间跳跃和倒退对预定作业的影响

如何避免夏令时 (DST) 时间跳跃和倒退对预定作业的影响

假设时区为 AEST(澳大利亚东部标准时间),开始时时间从凌晨 2 点跳到凌晨 3 点,结束时从凌晨 3 点倒转至凌晨 2 点。

夏令时从 10 月第一个星期日凌晨 2 点开始,时钟提前一小时。四月的第一个星期日凌晨 2 点(夏令时凌晨 3 点)结束,时钟拨慢一小时。

当 DST(冬季到夏季)时间发生变化时,时间会从凌晨 2 点跃升至凌晨 3 点。如果作业运行安排在此时间范围内,则作业将不会执行。

01:57:00
01:58:00
01:59:00
03:00:00 <--- job will not run as between 02:00 and 03:00 will disappear 
03:01:00
03:02:00

当时间从 DST(夏季改为冬季)时,时间会从凌晨 3 点倒转为凌晨 2 点。如果运行安排在此时间范围内,则运行将执行两次。

01:59:00
02:00:00
...
02:57:00
02:58:00
02:59:00
02:00:00 <--- job will be run twice as between 02:00 and 03:00 will repeat 
02:01:00
02:02:00 

如在夏令时,看来这是预料之中的。那么有什么可能的解决方案可以避免作业不运行或运行两次,同时仍然需要使用基于 DST 的时间呢?禁用夏令时建议使用固定的 GMT+N 或 GMT-N,但我们不能使用它,因为我们需要使用基于 DST 的时间。

是否不使用 Cron 或基于时间戳的编程,并且需要有一个使用纪元或 UTC 的调度程序?

答案1

一个选项是在 UTC+10 偏移时区下运行 cron,这样就不会进行 DST 调整。 看到这个问题有关如何执行此操作的示例。

另一个选项是将作业配置为在 DST 开始日运行两次:

0  2 *   *   *   /path/to/job
0  3 1-7 oct sun /path/to/job

因此,夏令时开始时就不会错过。

然后在脚本中您需要检查今天的作业是否尚未运行。一种方法是检查时间和时区的日期。我假设 DST 结束时的“date +”%a %m %H %Z””将报告:

02:59:00: Sun 10 02 ACDT
02:00:00: Sun 10 02 ACT

所以你的脚本可以检查:

now=`date +"%a %m %H %Z"`
if [ "$now" -eq "Sun 10 02 ACT" ]; then 
    echo "DST ended - not running"
    exit 0; 
fi;

相关内容