Спасибо за публикацию этого кода. Это определенно помогло мне, даже спустя 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. Я не смог найти опцию без дополнений для команды даты. Я попытался возиться со строкой {$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";
}
}
}
?>
person
epepepep
schedule
30.01.2015