假设时区为 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;