Спасибо за размещение этого кода. Это определенно помогло мне, даже через 6 лет.
Пытаясь реализовать, я обнаружил небольшую ошибку.
date('i G j n w', $time)
возвращает заполненное целым числом 0 для минут.
Позже в коде он выполняет модуль для этого дополненного 0 целого числа. PHP, кажется, не справляется с этим, как ожидалось.
$ php
<?php
print 8 % 5 . "\n";
print 08 % 5 . "\n";
?>
3
0
Как видите, 08 % 5
возвращает 0, тогда как 8 % 5
возвращает ожидаемое 3. Я не смог найти необязательный параметр для команды date. Я попытался поиграться со строкой {$time[$k]} % $1 === 0
(например, изменив {$time[$k]}
на ({$time[$k]}+0)
, но не смог заставить его сбросить отступ 0 во время модуля.
Итак, я просто изменил исходное значение, возвращаемое функцией даты, и удалил 0, выполнив $time[0] = $time[0] + 0;
.
Вот мой тест.
<?php
function parse_crontab($frequency='* * * * *', $time=false) {
$time = is_string($time) ? strtotime($time) : time();
$time = explode(' ', date('i G j n w', $time));
$time[0] = $time[0] + 0;
$crontab = explode(' ', $frequency);
foreach ($crontab as $k => &$v) {
$v = explode(',', $v);
$regexps = array(
'/^\*$/', # every
'/^\d+$/', # digit
'/^(\d+)\-(\d+)$/', # range
'/^\*\/(\d+)$/' # every digit
);
$content = array(
"true", # every
"{$time[$k]} === $0", # digit
"($1 <= {$time[$k]} && {$time[$k]} <= $2)", # range
"{$time[$k]} % $1 === 0" # every digit
);
foreach ($v as &$v1)
$v1 = preg_replace($regexps, $content, $v1);
$v = '('.implode(' || ', $v).')';
}
$crontab = implode(' && ', $crontab);
return eval("return {$crontab};");
}
for($i=0; $i<24; $i++) {
for($j=0; $j<60; $j++) {
$date=sprintf("%d:%02d",$i,$j);
if (parse_crontab('*/5 * * * *',$date)) {
print "$date yes\n";
} else {
print "$date no\n";
}
}
}
?>