`at` 怎么知道会有时间变化?

lef*_*out 12 timezone at

at就在昨天凌晨 2 点 40 分,我碰巧在玩弄。(不要问...)我尝试在未来一分钟安排活动(作为测试),并且 - 它只是没有发生。事件都在队列中,但他们只是在 2:41 时留在那里,没有发生任何事情。我放弃了,上床睡觉了。

发生了什么?好吧 - 结果今天夏令时在挪威结束(夏令时),所以今晚 2:41 确实发生了两次!果然,在第二个(即从夏令时看到的 3:41),at然后触发了那些预定的事件。

这是如何运作的?调度为什么以及如何知道时间变化,并选择第二次,而不是在时间超过指定的时间时才这样做?

fro*_*utz 21

at尝试解析给定的日期和时间,并在mktime()“夏令时”设置为 -1(不可用,自动检测)的情况下运行它。

at 源代码:

  tm1.tm_isdst = -1;
  t = mktime (&tm1);
Run Code Online (Sandbox Code Playgroud)

man 3 mktime

tm_isdst 字段中指定的值通知 mktime() 对于 tm 结构中提供的时间,夏令时 (DST) 是否有效:正值表示 DST 有效;零表示 DST 无效;负值意味着 mktime() 应该(使用时区信息和系统数据库来)尝试确定 DST 是否在指定时间生效。

mktime() 函数按如下方式修改 tm 结构的字段: [...] tm_isdst 分别设置为(不管其初始值如何)为正值或 0,以指示 DST 是否有效在指定的时间。

因此mktime()决定 DST 是否有效;并且它似乎更喜欢两个可能选择中的较晚日期(尽管文档中不清楚该决定是如何做出的)。

at然后将其转换为 UNIX 时间戳(自 1970 年 1 月 1 日以来的秒数)。一旦你有了它,就不再有时间改变这样的事情了。来回改变时钟一小时只会改变人类对时间的表示,或者你所在的时区;它不会更改自纪元以来的秒数,也不会更改任务运行之前的秒数。


我尝试在未来一分钟安排活动(作为测试)

在旁注中,您可以使用类似next minute, 将在下一分钟运行,时间更改或不运行的表达式。