PHP - 获取下一个crontab运行的日期

fis*_*lin 10 php cron

我想得到下一个日期从一个给定的字符串运行cron,如Cron Format with secondsparameter(不完全等于cron格式).

我的代码:

$cron_format = explode(" ", "00 00 00 01 * *"); // <second> <minute> <hour> <day> <month> <week_day>
$date_diff   = explode(" ", "s i H d m w");     // php Date @link http://php.net/manual/en/function.date.php
$format = [];

foreach( $date_diff as $key=>$value) {
    $format[$value] = $cron_format[$key] !== "*" ? date($value, strtotime($cron_format[$key])) : date($value);
}

$spf = sprintf(
"%s-%s-%s %s:%s:%s", 
date("Y"), $format["m"], $format["d"], $format["H"], $format["i"], $format["s"]
);

$date = DateTime::createFromFormat("Y-m-d H:i:s", $spf);

// returns 2018-03-01 00:00:00, expected was 2018-04-01 00:00:00
echo $date->format("Y-m-d H:i:s"); 
Run Code Online (Sandbox Code Playgroud)

小提琴

2018-03-01 00:00:00按预期读取,但我正在寻找的是获得下一个Crontab运行日期的方法(2018-04-01 00:00:00).

设置添加月份的方法并不能解决问题,因为cron格式可以按小时设置,如下所示:

<second> <minute> <hour> <day> <month> <week_day>
   00       00      *      *      *         *
Run Code Online (Sandbox Code Playgroud)

小智 13

无需为此编写更多代码.请使用下面的库来做到这一点

https://github.com/mtdowling/cron-expression

用法:

<?php
// Works with cron expression
$cron = new Cron\CronExpression::factory('15 2,6-12 */15 1 *');
$cron->getNextRunDate();
Run Code Online (Sandbox Code Playgroud)

  • 为何选择@fiskolin? (5认同)
  • 谢谢,但我试图在不安装公共图书馆的情况下达到相同的结果. (2认同)
  • 只是提醒mtdowling repo已被弃用而支持dragonmantank repo:https://github.com/dragonmantank/cron-expression (2认同)

Ber*_*ard 6

我玩了一下,这是我作为一个功能的结果.基本上我拆分元素,检查通配符的值.如果找到它将忽略所有其他通配符并使用第一个通配符+1设置元素的值.此外,我检查d和m的零值,如果发现它们被值1替换.最后检查,如果当前年份的日期小于当前日期.如果是,它将使用当前年份,如果没有它将使用下一年.

 function calculate_next_cronjob($cronjob, $elementpositions){

  $wildcard = false;
  $elements = preg_split('/[^\d*]+/', $cronjob);

  foreach(preg_split('/[^a-z]+/i', $elementpositions) as $key => $element){

    $value[$element] = $elements[$key];

    switch($element){
     case 's':
      if($value[$element] == '*'){
       $value[$element] = date('s') + 1;
       $wildcard = true;
      }
     break;
     case 'i':
      if($value[$element] == '*'){
       $value[$element] = date('i') + ($wildcard === true ? 0 : 1);
       $wildcard = true;
      }
     break;
     case 'H': 
      if($value[$element] == '*'){
       $value[$element] = date('H') + ($wildcard === true ? 0 : 1);
       $wildcard = true;
      }
     break;
     case 'd': 
      if($value[$element] == '*'){
       $value[$element] = date('d') + ($wildcard === true ? 0 : 1);
       $wildcard = true;
      }
      if(intval($value[$element]) == 0){
       $value[$element] = 1;          
      }
     break;
     case 'm': 
      if($value[$element] == '*'){
       $value[$element] = date('m') + ($wildcard === true ? 0 : 1);
       $wildcard = true;
      }
      if(intval($value[$element]) == 0){
       $value[$element] = 1; 
      }
     break;
      default:
      unset($value[$element]);
    }

  }

  $cy = date('Y');
  $ny = $cy + 1;

  if(time() < mktime($value['H'], $value['i'], $value['s'], $value['m'], $value['d'], $cy)){
   $value['Y'] = $cy;
  }else{
   $value['Y'] = $ny; 
  }

  return date('Y-m-d H:i:s', mktime($value['H'], $value['i'], $value['s'], $value['m'], $value['d'], $value['Y']));

 }  
Run Code Online (Sandbox Code Playgroud)

测试运行:

 $cronjobs   = array();
 $cronjobs[] = array('00 00 00 00 *  00', 's  i  H  d m N');
 $cronjobs[] = array('00 00 00 *  *  00', 's  i  H  d m N');
 $cronjobs[] = array('00 00 *  *  *  00', 's  i  H  d m N');
 $cronjobs[] = array('00 *  *  *  *  00', 's  i  H  d m N');
 $cronjobs[] = array('*  *  *  *  *  00', 's  i  H  d m N');

 echo '<table>';
 foreach($cronjobs as $data){
  echo '<tr><td>';
  echo $data[0];
  echo '</td><td>';
  echo $data[1];
  echo '</td><td>';
  echo calculate_next_cronjob($data[0], $data[1]);
  echo '</td></tr>';
 }
 echo '</table>';
Run Code Online (Sandbox Code Playgroud)

输出:

00 00 00 00 * 00 s i H d m N 2018-05-01 00:00:00 
00 00 00 *  * 00 s i H d m N 2018-04-17 00:00:00 
00 00 *  *  * 00 s i H d m N 2018-04-16 09:00:00 
00 *  *  *  * 00 s i H d m N 2018-04-16 08:25:00 
*  *  *  *  * 00 s i H d m N 2018-04-16 08:24:59 
Run Code Online (Sandbox Code Playgroud)