Open geryguilbon opened 7 years ago
Not pretty or very good but this works:
<?php
$start = "2010-01-12 00:00:00";
$end = "2011-01-13 00:00:00";
$ahead = 0;
$cron = Cron\CronExpression::factory('@monthly');
$init = $cron->getNextRunDate($start, $ahead)->format('Y-m-d H:i:s');
while (strtotime($init) <= strtotime($end)) {
echo "<pre>$init\n<pre>";
$ahead++;
$init = $cron->getNextRunDate($start, $ahead)->format('Y-m-d H:i:s');
}
?>
Same for "get next X runs" or is that possible already?
Needed a from-to last days ... here is a concept i would suggest:
EDIT: i just realizeed that the param $invert
makes no sense in this method. So ignore it - should be provided as false
always at getMultipleRunDates
=)
function getMultipleRunDatesByTimeframe(
$cronExpression,
$from = 'now',
$to = 'now + 1 hour',
// bool $invert = false,
bool $allowCurrentDate = false,
$timeZone = null
) {
$model = new CronExpression($cronExpression);
$from = new DateTime($from);
$to = new DateTime($to);
$matches = [];
while ($from <= $to) {
$match = $model->getMultipleRunDates(
1, // $total,
$from, // $currentTime,
false, // $invert,
$allowCurrentDate,
$timeZone
)[0];
$matches[] = $match;
// After every run re-set the $from var to not run into "Impossible CRON expression".
// Example:
// $cronExpression : "*/15 * * * *"
// $from : "2023-07-29 16:12:49"
// $match : "2023-07-29 16:15:00"
// $from re-set : "2023-07-29 16:15:00"
$from = clone $match;
// After the first run we need to set the var $allowCurrentDate to value false
// to not keep looping on the same datetime.
// Example:
// we just got "2023-07-29 19:15:00"
// and would get "2023-07-29 19:15:00" again, and again, ... .
$allowCurrentDate = false;
}
return $matches;
}
$cronExpression = '*/15 * * * *';
$from = 'now';
$to = 'now + 1 hour';
// $invert = false;
$allowCurrentDate = true;
$timeZone = null;
$matches = getMultipleRunDatesByTimeframe(
$cronExpression,
$from,
$to,
// $invert,
$allowCurrentDate,
$timeZone
);
I used getMultipleRunDates
because its public unlike getRunDate
.
I choose to get always 1 single run date to not run into $maxIterationCount
error.
And this makes it actually pretty fast. Expression */15 * * * *
from 2023-01-01
to 2023-12-31
took 0.354930
sec.
Suggestions:
There are atm 3 places of $currentTime
checks at
https://github.com/dragonmantank/cron-expression/blob/master/src/Cron/CronExpression.php#L317
https://github.com/dragonmantank/cron-expression/blob/master/src/Cron/CronExpression.php#L403
https://github.com/dragonmantank/cron-expression/blob/master/src/Cron/CronExpression.php#L445
I would suggest to add a new method getDatetimeObject($datetime)
to be able to
Implement a metod getMultipleRunDatesByTimeframe(...)
like
public function getMultipleRunDatesByTimeframe(
$from = 'now',
$to = 'now + 1 hour',
// bool $invert = false,
bool $allowCurrentDate = false,
$timeZone = null
): array {}
and use the new|suggested getDatetimeObject(...)
method to
$from
parameter$to
parameter.The code for this method would be ofc the one in the concept above, without the need of the cron expression model creation.
I think this could be great to have this feature implemented =)