Gracias por publicar este código. Definitivamente me ayudó, incluso 6 años después.
Intentando implementar encontré un pequeño error.
date('i G j n w', $time)
devuelve 0 enteros rellenos para los minutos.
Más adelante en el código, hace un módulo en ese 0 entero acolchado. PHP no parece manejar esto como se esperaba.
$ php
<?php
print 8 % 5 . "\n";
print 08 % 5 . "\n";
?>
3
0
Como se puede ver, 08 % 5
devuelve 0, mientras que 8 % 5
devuelve la esperada 3. No pude encontrar una opción no acolchado para el comando date. He intentado tocar el violín con la línea {$time[$k]} % $1 === 0
(como cambiar {$time[$k]}
-({$time[$k]}+0)
, pero no pude conseguir que deje caer el relleno de 0 durante el módulo.
Así, acabé cambiando el valor original devuelto por la función de fecha y eliminado del 0 al ejecutar $time[0] = $time[0] + 0;
.
Aquí es mi prueba.
<?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";
}
}
}
?>
dlamblin: ¿su segunda versión tiene un bucle invariante? Obviamente, lo que está haciendo es acercarse cada vez más al resultado. Pero estoy tratando de demostrar su para mí mismo y no puedo entender qué sería el invariante de lazo. – eeeeaaii
¿Adivina qué? No hay bucle invariante - ** ¡porque no es realmente un bucle! ** Básicamente es una serie de declaraciones goto enmascaradas como un bucle Para probar esto, tenga en cuenta que podría reemplazar el while (true) con un do {...} while (falso). – eeeeaaii
en realidad no, porque "continuar" en realidad salta al final de un ciclo, no al principio. en java. Entonces todavía tienes que decir "do" ...; descanso; } while (true) – eeeeaaii