나는 개인적인 프레임 워크에서 작업 스케줄러를 설계하고 있으며, 유연하지 않은 "every n 분 /시/일"실행을 피하려고하고있다. 쉽게 구현할 수 있습니다. 제가하고 싶은 것은 cron 스케줄링을 모방하는 것입니다. 패턴을 분할하고 현재 날짜의 다음 날짜 (일)에 대한 다음 값을 계산하는 기능을 갖추고 있지만, 내가하고있는 것보다 더 쉬운 것이 있거나 더 나은 것이 있다면 계속 추진하고 싶지는 않습니다. 내가하려는 일을하는 방법.PHP에서 cron next-run-time 계산하기
/**
* Takes pattern(s) for various time attributes and calculates the next time the task should run
*
* @param mixed $minute Pattern or value of minute: 0-59 or 15,45 or * or * /5 (every 5 minutes)
* @param mixed $hour Pattern or value of hour: 0-23 or 0,6,12 or * or * /2 (every 2 hours)
* @param mixed $date Pattern or value of date: 1-31 or 1,15 or * or * /5 (every 5 days)
* @param mixed $day Pattern or value of weekday: 0-7 or 0,1,7 or * or * /7 (every 7 days) - takes precedence over date
* @return string Timestamp of next run time
*/
public static function calcNextRun($minute, $hour, $date, $day)
{
# Simplest first, if all * then we run every minute. Return timestamp for next whole minute
if ($minute == '*' && $hour == '*' && $date == '*' && $day == '*')
return mktime(date("H"), date("i"), 0) + 60; # Prettier than time() + 60, isn't that reason enough?
# Default to current values
$nextDate = date("d");
$nextMonth = date("m");
$nextYear = date("Y");
$nextDay = date("N");
$nextHour = date("H");
$nextMinute = date("i");
# Calculate month date to run on, using multiple dates in the presence of , or -
if(strstr($date, ',') || strstr($date, '-'))
{
# Variable to determine whether the date has been set or not
$dateSet = false;
# Determine if there's a range in thurr
$rangeExists = (strstr($date, '-')) ? true : false ;
# Set up the $dates array, exploding if multiple values is present
$dates = array();
if (strstr($date, ','))
$dates = explode(',', $date);
else
$dates[] = $date;
# If we have a range(s) present then we expand them into full stuffs
foreach ($dates as $key => $val)
if (strstr($val, '-'))
$dates = array_merge($dates, self::expandRange($val)); # Merge the expanded range into the $dates array
# Loop through the $dates array and remove any lingering ranges
foreach ($dates as $key => $val)
if (strstr($val, '-'))
unset($dates[ $key ]);
# Sort the array
sort($dates);
# Determine the next lowest value
foreach($dates as $val)
{
# If the value is higher than the maximum number of dates this month, lower it to that
if ($val > date("t"))
$val = date("t");
# If $val is higher than today's date, we use that
if ($val > date("d"))
{
$nextDate = $val;
$dateSet = true;
break; # We're done, we have our value
}
}
# If the date has not been set, add one to the month and use the lowest value in the array
if (!$dateSet)
{
# Increment the month. Maybe the year. Hurr hurr
if ($nextMonth == 12)
{
$nextMonth = 1;
$nextYear++;
}
else
$nextMonth++;
# Set the next day to the lowest value in the array
$nextDate = $dates[0];
}
}
elseif (strstr($date, '/')) # Every n days
{
$parts = explode('/', $date);
$numDays = array_pop($parts);
# Calculate the timestamp of n days from now
$nDayTime = time() + ($numDays * 86400); # 86400 seconds in a day
# Update values of $nextVars
$nextDate = date("d", $nDayTime);
$nextMonth = date("m", $nDayTime);
$nextYear = date("Y", $nDayTime);
$nextDay = date("N", $nDayTime);
}
elseif ($date == (int)$date)
{
if ($date < date("j"))
{
# Determine if the month pushes into the next year
if ($nextMonth == 12)
{
$nextMonth = 1;
$nextYear++;
}
else
$nextMonth++;
}
$nextDate = $date;
}
# Return the new timestamp!
return mktime($nextHour, $nextMinute, 0, $nextMonth, $nextDate, $nextYear);
}
/**
* Takes a range and returns an array with all values belonging to that range
*
* @param string $range Two values split by a hyphen, ie: 1-5, 0-9, etc.
* @return array Array of values between the two parts of the range
*/
private static function expandRange($range)
{
# Get the parts of the range
$range = explode('-', $range);
# Sort just in case the range is handed to us backwards. <_<
sort($range);
# Set up our return array
$returnArray = array();
# Populate the return array with all values between min and max
for($i=$range[0];$i<=$range[1];$i++)
$returnArray[] = $i;
return $returnArray;
}
나는 크론이 사용하는 매개 변수의 다섯 가지를 사용하여 상관하지 않지만, 어느 쪽이든 나는 쉽게 제공하는 패턴과 일치하는 다음 타임 스탬프를 계산할 수 있어야합니다.
누구든지이 작업을 수행하기위한 권장 사항이 있습니까? 나는 패턴 (1-7,10,15 또는 */5 또는 * 또는 무엇이든)과 현재의 val (현재의 분, 날의 어떤 날)을 취해 다음 값을 반환하는 함수를 생성하려고 생각하고있다. 해당 패턴과 일치하거나 현재 값보다 높습니다.