当我的服务器自动使用 DST 时,如何使用 cron 来安排在不支持 DST 的应用程序上实现夏令时的脚本?

当我的服务器自动使用 DST 时,如何使用 cron 来安排在不支持 DST 的应用程序上实现夏令时的脚本?

我的服务器(运行 ubuntu 8.04LTS 服务器)报告的当前时间为 BST 晚上 9:38。BST(英国夏令时)比 UTC(或格林威治标准时间)早 1 小时,如果你真的想混淆的话

议会法案规定,英国使用 BST 来

该时间段从三月的最后一个星期日凌晨一点(格林威治标准时间)开始,到十月的最后一个星期日凌晨一点(格林威治标准时间)结束。

在 cron 中安排这个没有问题,但我不知道应该使用什么日期格式/时区。我是否应该将其设置为在凌晨 1 点前进,但在结束时在凌晨 2 点后退?如果机器使用 BST,那么这是有道理的,但我担心该 cron 不会在凌晨 2 点触发,因为系统时钟可能会在它有机会触发之前重置回凌晨 1 点 - 从而使我的脚本运行延迟 1 小时。

或者它只是使用 UTC?

答案1

答案在于 cron 源(您可以通过 获取apt-get source cron),特别是文件 159-272 行的主循环中cron.c

crond休眠一分钟,然后唤醒并查询系统时间,将其与自己的时间观念进行比较(即,如果时钟没有任何改变,现在是什么时间)。根据实际时间和预期时间之间的差异,crond采取不同的行动;其中两个与您的情况相关:

  1. 时间向前跳跃了 5 分钟以上但不到 3 小时(夏令时开始):cron 运行在实际时间安排的通配符作业,以及在计算时间和实际时间之间的固定时间安排的任何作业。相关来源位于第 221-247 行:

      /*
       * case 2: timeDiff is a medium-sized positive number,
       * for example because we went to DST run wildcard
       * jobs once, then run any fixed-time jobs that would
       * otherwise be skipped if we use up our minute
       * (possible, if there are a lot of jobs to run) go
       * around the loop again so that wildcard jobs have
       * a chance to run, and we do our housekeeping
       */
      Debug(DSCH, ("[%d], DST begins %d minutes to go\n",
          getpid(), timeRunning - virtualTime))
      /* run wildcard jobs for current minute */
      find_jobs(timeRunning, &database, TRUE, FALSE);
    
    
      /* run fixed-time jobs for each minute missed */ 
      do {
         if (job_runqueue())
                 sleep(10);
         virtualTime++;
         find_jobs(virtualTime, &database, FALSE, TRUE);
         set_time();
      } while (virtualTime< timeRunning &&
          clockTime == timeRunning);
      break;
    
  2. 时间已倒退不到 3 小时(夏令时结束):只运行通配符作业,跳过固定时间表作业,因为它们已经运行。相关源代码位于第 247-258 行:

    /*
     * case 3: timeDiff is a small or medium-sized
     * negative num, eg. because of DST ending just run
     * the wildcard jobs. The fixed-time jobs probably
     * have already run, and should not be repeated
     * virtual time does not change until we are caught up
     */
    Debug(DSCH, ("[%d], DST ends %d minutes to go\n",
        getpid(), virtualTime - timeRunning))
    find_jobs(timeRunning, &database, TRUE, FALSE);
    break;
    

因此,当进入 DST 时,您应该不会遇到任何问题:您的脚本将会运行(在时间跳跃之前或之后立即运行)。

退出 DST 时,如果你安排了(固定时间)作业,则可能会被跳过确切地1 点。我的建议是将运行安排在 1 点前 1 分钟,或者 2 点(或 2 点之后)。

答案2

您可以尝试在 中切换UTC=noyes或 为/etc/default/rcS。为此,请运行:

gksu gedit /etc/default/rcS
  • 改成,UTC=noUTC=yes或者
  • 改成。UTC=yesUTC=no

保存文件,退出文本编辑器,然后重新启动电脑。

相关内容