I want to get the next date to run the cron from a given string like Cron Format with seconds
parameter (not fully equal as cron format).
My code:
$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");
Fiddle
It reads 2018-03-01 00:00:00
as expected, but what I am looking for is a way to get next Crontab run date (2018-04-01 00:00:00)
.
Setting a way to add a month does not solve the problem, since the cron format could be set hourly, as:
<second> <minute> <hour> <day> <month> <week_day>
00 00 * * * *
No need to write more code for that. Please use below library to do that
https://github.com/mtdowling/cron-expression
Usage:
<?php
// Works with cron expression
$cron = new Cron\CronExpression::factory('15 2,6-12 */15 1 *');
$cron->getNextRunDate();
I played a little bit around and here is my result as a function. Basically I split the elements, check the values for Wildcards. If found it will ignore all other Wildcards and set the value for the element with the first Wildcard +1. Further I check the d and m for zero-values, and if found they are replaced by the value 1. In the end i check, if the date with the current year would be smaller than the current date. if yes, it will use the current year, if no it will use the next year.
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']));
}
Testrun:
$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>';
Output:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With