Функция PHP, которая получает строку cron и возвращает следующую временную метку запуска

Мне нужно разработать систему задач, которая должна работать на серверах, которые не поддерживают crontab.

Я спрашиваю, есть ли какой-либо существующий код, который может взять строку cron (например, «0 0,12 1 * / 2 *» и вернуть отметку времени следующего запланированного прогона.

Если такой код не может быть найден, то как мне начать с этого?

Вы можете использовать этот класс PHP-Parse-cron-strings-and-compute-schedules

Он также рассчитает последний запланированный прогон

Используйте эту функцию:

function parse_crontab($time, $crontab) {$time=explode(' ', date('i G jn w', strtotime($time))); $crontab=explode(' ', $crontab); foreach ($crontab as $k=>&$v) {$time[$k]=intval($time[$k]); $v=explode(',', $v); foreach ($v as &$v1) {$v1=preg_replace(array('/^\*$/', '/^\d+$/', '/^(\d+)\-(\d+)$/', '/^\*\/(\d+)$/'), array('true', $time[$k].'===\0', '(\1<='.$time[$k].' and '.$time[$k].'<=\2)', $time[$k].'%\1===0'), $v1 ); } $v='('.implode(' or ', $v).')'; } $crontab=implode(' and ', $crontab); return eval('return '.$crontab.';'); } var_export(parse_crontab('2011-05-04 02:08:03', '*/2,3-5,9 2 3-5 */2 *')); var_export(parse_crontab('2011-05-04 02:08:03', '*/8 */2 */4 */5 *')); 

Вы можете попробовать это: http://mtdowling.com/blog/2012/06/03/cron-expressions-in-php/, которые используют библиотеку парсеров PHP Cron-Expression, php-класс https://github.com/mtdowling / хрон-выражение

Я обнаружил, что дийизм имеет отличный ответ, но нашел ключевую ошибку.

Если вы введете время cron, например 0 * * * * , оно будет работать через 0, 8, 6 и 9 минут. Код дает условие 08===0 , которое возвращает true, потому что PHP интерпретирует числа, начинающиеся с 0, как восьмеричные, а 08 и 09 – недействительные восьмеричные числа, поэтому они интерпретируются как 0. Более подробная информация здесь.

Как предотвратить PHP от выполнения восьмеричной математики в условных выражениях? (почему 08 === 0)

Вот фиксированная и хорошо прокомментированная версия кода дийизма.

 // Parse CRON frequency function parse_crontab($time, $crontab) { // Get current minute, hour, day, month, weekday $time = explode(' ', date('i G jn w', strtotime($time))); // Split crontab by space $crontab = explode(' ', $crontab); // Foreach part of crontab foreach ($crontab as $k => &$v) { // Remove leading zeros to prevent octal comparison, but not if number is already 1 digit $time[$k] = preg_replace('/^0+(?=\d)/', '', $time[$k]); // 5,10,15 each treated as seperate parts $v = explode(',', $v); // Foreach part we now have foreach ($v as &$v1) { // Do preg_replace with regular expression to create evaluations from crontab $v1 = preg_replace( // Regex array( // * '/^\*$/', // 5 '/^\d+$/', // 5-10 '/^(\d+)\-(\d+)$/', // */5 '/^\*\/(\d+)$/' ), // Evaluations // trim leading 0 to prevent octal comparison array( // * is always true 'true', // Check if it is currently that time, $time[$k] . '===\0', // Find if more than or equal lowest and lower or equal than highest '(\1<=' . $time[$k] . ' and ' . $time[$k] . '<=\2)', // Use modulus to find if true $time[$k] . '%\1===0' ), // Subject we are working with $v1 ); } // Join 5,10,15 with `or` conditional $v = '(' . implode(' or ', $v) . ')'; } // Require each part is true with `and` conditional $crontab = implode(' and ', $crontab); // Evaluate total condition to find if true return eval('return ' . $crontab . ';'); } 

В функции parse_crontab :

Замените $time[$k] на intval($time[$k]) внутри строки preg_replace
для правильного сравнения двух base10 чисел 10.

Я написал очень мощный PHP-класс под названием CalendarEvent давным-давно:

https://github.com/cubiclesoft/php-misc/

Он поддерживает два разных синтаксиса шаблонов. Обычный cron не может обрабатывать определенные сложные шаблоны, тогда как синтаксис CalendarEvent по умолчанию обрабатывает любой шаблон планирования, который вам когда-либо понадобится. Поддержка синтаксиса шаблона cron на самом деле является резервным (префикс cron lines cron и пробел).

CalendarEvent был написан главным образом как класс вычисления событий календаря и только что получил поддержку механизмов «следующего триггера» в стиле cron. Он на самом деле предназначен для вычисления всего графика в течение нескольких месяцев с целью отображения календаря пользователю (отсюда и название класса). Я также использовал этот класс в качестве промежуточного решения для перевода событий между платформами календаря. Это более редкий сценарий – я использовал его чаще всего для решений Cron-типа AddSchedule () / NextTrigger ().