Calculate when a cron job will be executed then next time

后端 未结 8 950
庸人自扰
庸人自扰 2020-12-02 08:19

I have a cron \"time definition\"

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          


        
8条回答
  •  误落风尘
    2020-12-02 08:48

    Use this function:

    function parse_crontab($time, $crontab)
             {$time=explode(' ', date('i G j n w', strtotime($time)));
              $crontab=explode(' ', $crontab);
              foreach ($crontab as $k=>&$v)
                      {$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 *'));
    

    Edit Maybe this is more readable:

     &$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};");
        }
    

    Usage:

提交回复
热议问题