我有一个时间表“时间定义”
1 * * * * (every hour at xx:01) 2 5 * * * (every day at 05:02) 0 4 3 * * (every third day of the month at 04:00) * 2 * * 5 (every minute between 02:00 and 02:59 on fridays)
而且我有一个Unix时间戳。
有什么明显的方法可以找到(计算)下一次(在给定的时间戳之后)要执行的作业?
我正在使用PHP,但是问题应该与语言无关。
[更新]
类“ PHP Cron Parser ”(由Ray推荐)将计算应该执行CRON作业的最后时间,而不是下一次。
使其变得更容易:在我的情况下,cron时间参数仅是绝对值,单个数字或“ *”。没有时间范围,也没有“ * / 5”间隔。
基本上,这与检查当前时间是否符合条件相反。所以像这样:
//Totaly made up language next = getTimeNow(); next.addMinutes(1) //so that next is never now done = false; while (!done) { if (cron.minute != '*' && next.minute != cron.minute) { if (next.minute > cron.minute) { next.addHours(1); } next.minute = cron.minute; } if (cron.hour != '*' && next.hour != cron.hour) { if (next.hour > cron.hour) { next.hour = cron.hour; next.addDays(1); next.minute = 0; continue; } next.hour = cron.hour; next.minute = 0; continue; } if (cron.weekday != '*' && next.weekday != cron.weekday) { deltaDays = cron.weekday - next.weekday //assume weekday is 0=sun, 1 ... 6=sat if (deltaDays < 0) { deltaDays+=7; } next.addDays(deltaDays); next.hour = 0; next.minute = 0; continue; } if (cron.day != '*' && next.day != cron.day) { if (next.day > cron.day || !next.month.hasDay(cron.day)) { next.addMonths(1); next.day = 1; //assume days 1..31 next.hour = 0; next.minute = 0; continue; } next.day = cron.day next.hour = 0; next.minute = 0; continue; } if (cron.month != '*' && next.month != cron.month) { if (next.month > cron.month) { next.addMonths(12-next.month+cron.month) next.day = 1; //assume days 1..31 next.hour = 0; next.minute = 0; continue; } next.month = cron.month; next.day = 1; next.hour = 0; next.minute = 0; continue; } done = true; }
我可能已经写了一些倒退。如果不是在每个主记录中都只是将当前时间等级加1,然后将较小的时间等级设置为0,然后继续,则它可能会更短,而不是在每个主要项目中都执行大于检查的步骤。但是,那么您将循环更多。像这样:
//Shorter more loopy version next = getTimeNow().addMinutes(1); while (true) { if (cron.month != '*' && next.month != cron.month) { next.addMonths(1); next.day = 1; next.hour = 0; next.minute = 0; continue; } if (cron.day != '*' && next.day != cron.day) { next.addDays(1); next.hour = 0; next.minute = 0; continue; } if (cron.weekday != '*' && next.weekday != cron.weekday) { next.addDays(1); next.hour = 0; next.minute = 0; continue; } if (cron.hour != '*' && next.hour != cron.hour) { next.addHours(1); next.minute = 0; continue; } if (cron.minute != '*' && next.minute != cron.minute) { next.addMinutes(1); continue; } break; }