根据 cron 规范计算下一个计划时间

发布于 2024-10-10 17:34:31 字数 248 浏览 3 评论 0原文

在给定当前时间和 cron 规范的情况下,计算事件下一次运行时间的有效方法是什么?

我正在寻找“每分钟循环检查是否符合规范”以外的东西。

规范的示例可能是:

  • 每个月,1 日和 15 日 15:01
  • 每小时 10、20、30、40、50 分钟,

Python 代码很可爱,但伪代码或高级描述也将受到赞赏。

[更新] 假设规范已经解析并且采用某种合理的格式。

What's an efficient way to calculate the next run time of an event given the current time and a cron spec?

I'm looking for something other than "loop through every minute checking if it matches spec".

Examples of specs might be:

  • Every month, on the 1st and 15 at 15:01
  • At 10,20,30,40,50 mins past the hour every hour

Python code would be lovely but psuedo code or high level description would also be appreciated.

[Update] Assume the spec is already parsed and is in some reasonable format.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

無心 2024-10-17 17:34:31

看看它,我认为你需要:

  • 将 chron 规范解析为五个包含每个字段可接受值的数组;
  • 将“now”解析为每个字段的值;
  • 按分钟、小时、{某月某日或某周}、某年某月的顺序:查找匹配或超过当前值的最低数组值,并纠正进位。

我不知道如何同时处理星期几和月份;我确信有一种方法,但另一方面,我认为我从未见过真正指定这两者的规范。我认为为其中一个编写一个处理程序并在收到两者时抛出一个错误就足够了。

编辑:显然如果同时指定了星期几和月份日,它应该在两者触发 - 即,如果规则是“15日,星期三”,它将在每个15号每个星期三触发。

croniter 包可以做你想要的事情:

import croniter
import datetime

now = datetime.datetime.now()
sched = '1 15 1,15 * *'    # at 3:01pm on the 1st and 15th of every month
cron = croniter.croniter(sched, now)

for i in range(4):
    nextdate = cron.get_next(datetime.datetime)
    print nextdate

打印,

2011-01-15 15:01:00
2011-02-01 15:01:00
2011-02-15 15:01:00
2011-03-01 15:01:00

尽管如果它被写成一个实际的迭代器会很好。也许我已经有了下一个项目;-)

Just looking at it, I think you need to:

  • parse the chron spec to five arrays containing acceptable values for each field;
  • parse 'now' to a value for each field;
  • in order of minute, hour, {day-of-month OR day-of-week}, month-of year: find the lowest array value that matches or exceeds the current value, correcting for carry.

I don't know how to handle day-of-week and day-of-month simultaneously; I am sure there is a way, but on the other hand I don't think I've ever seen a spec that actually specified both. I think it would be sufficient to write a handler for either and throw an error if you receive both.

Edit: apparently if day-of-week and day-of-month are both specified, it is supposed to fire on both - ie if the rule is '15th, Wednesday' it will fire on every 15th and every Wednesday.

The croniter package does what you want:

import croniter
import datetime

now = datetime.datetime.now()
sched = '1 15 1,15 * *'    # at 3:01pm on the 1st and 15th of every month
cron = croniter.croniter(sched, now)

for i in range(4):
    nextdate = cron.get_next(datetime.datetime)
    print nextdate

prints

2011-01-15 15:01:00
2011-02-01 15:01:00
2011-02-15 15:01:00
2011-03-01 15:01:00

although it would be nice if it were written as an actual iterator. Maybe I've got my next project ;-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文