Google бесполезен в этом случае, потому что поиск флагов бесполезен
blockquote>К счастью, Bash Reference Manual доступно в Интернете, в http://www.gnu.org/software/bash/manual/bashref.html. Это первый хит, когда вы Google для «Bash manual». & sect; 6.4 «Условные выражения Bash» говорит:
-f file
Истинно, если file существует и является обычным файлом.
blockquote> blockquote>
Это в основном делает реверс проверки, если текущее время соответствует условиям. так что-то как:
//Totaly made up language
next = getTimeNow();
next.addMinutes(1) //so that next is never now
done = false;
while (!done) {
if (cron.minute != '*' && next.minute != cron.minute) {
if (next.minute > cron.minute) {
next.addHours(1);
}
next.minute = cron.minute;
}
if (cron.hour != '*' && next.hour != cron.hour) {
if (next.hour > cron.hour) {
next.hour = cron.hour;
next.addDays(1);
next.minute = 0;
continue;
}
next.hour = cron.hour;
next.minute = 0;
continue;
}
if (cron.weekday != '*' && next.weekday != cron.weekday) {
deltaDays = cron.weekday - next.weekday //assume weekday is 0=sun, 1 ... 6=sat
if (deltaDays < 0) { deltaDays+=7; }
next.addDays(deltaDays);
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.day != '*' && next.day != cron.day) {
if (next.day > cron.day || !next.month.hasDay(cron.day)) {
next.addMonths(1);
next.day = 1; //assume days 1..31
next.hour = 0;
next.minute = 0;
continue;
}
next.day = cron.day
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.month != '*' && next.month != cron.month) {
if (next.month > cron.month) {
next.addMonths(12-next.month+cron.month)
next.day = 1; //assume days 1..31
next.hour = 0;
next.minute = 0;
continue;
}
next.month = cron.month;
next.day = 1;
next.hour = 0;
next.minute = 0;
continue;
}
done = true;
}
я, возможно, записал что немного назад. Также это может быть намного короче, если в каждом основном, если вместо того, чтобы делать, чем больше, чем проверка Вы просто увеличиваете класс текущего времени одним и устанавливаете, тем меньшие классы времени к 0 тогда продолжаются; однако тогда Вы будете цикличным выполнением намного больше. Как так:
//Shorter more loopy version
next = getTimeNow().addMinutes(1);
while (true) {
if (cron.month != '*' && next.month != cron.month) {
next.addMonths(1);
next.day = 1;
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.day != '*' && next.day != cron.day) {
next.addDays(1);
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.weekday != '*' && next.weekday != cron.weekday) {
next.addDays(1);
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.hour != '*' && next.hour != cron.hour) {
next.addHours(1);
next.minute = 0;
continue;
}
if (cron.minute != '*' && next.minute != cron.minute) {
next.addMinutes(1);
continue;
}
break;
}
Для любого заинтересованного, вот моя заключительная реализация PHP, которая в значительной степени равняется dlamblin псевдо коду:
class myMiniDate {
var $myTimestamp;
static private $dateComponent = array(
'second' => 's',
'minute' => 'i',
'hour' => 'G',
'day' => 'j',
'month' => 'n',
'year' => 'Y',
'dow' => 'w',
'timestamp' => 'U'
);
static private $weekday = array(
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
0 => 'sunday'
);
function __construct($ts = NULL) { $this->myTimestamp = is_null($ts)?time():$ts; }
function __set($var, $value) {
list($c['second'], $c['minute'], $c['hour'], $c['day'], $c['month'], $c['year'], $c['dow']) = explode(' ', date('s i G j n Y w', $this->myTimestamp));
switch ($var) {
case 'dow':
$this->myTimestamp = strtotime(self::$weekday[$value], $this->myTimestamp);
break;
case 'timestamp':
$this->myTimestamp = $value;
break;
default:
$c[$var] = $value;
$this->myTimestamp = mktime($c['hour'], $c['minute'], $c['second'], $c['month'], $c['day'], $c['year']);
}
}
function __get($var) {
return date(self::$dateComponent[$var], $this->myTimestamp);
}
function modify($how) { return $this->myTimestamp = strtotime($how, $this->myTimestamp); }
}
$cron = new myMiniDate(time() + 60);
$cron->second = 0;
$done = 0;
echo date('Y-m-d H:i:s') . '<hr>' . date('Y-m-d H:i:s', $cron->timestamp) . '<hr>';
$Job = array(
'Minute' => 5,
'Hour' => 3,
'Day' => 13,
'Month' => null,
'DOW' => 5,
);
while ($done < 100) {
if (!is_null($Job['Minute']) && ($cron->minute != $Job['Minute'])) {
if ($cron->minute > $Job['Minute']) {
$cron->modify('+1 hour');
}
$cron->minute = $Job['Minute'];
}
if (!is_null($Job['Hour']) && ($cron->hour != $Job['Hour'])) {
if ($cron->hour > $Job['Hour']) {
$cron->modify('+1 day');
}
$cron->hour = $Job['Hour'];
$cron->minute = 0;
}
if (!is_null($Job['DOW']) && ($cron->dow != $Job['DOW'])) {
$cron->dow = $Job['DOW'];
$cron->hour = 0;
$cron->minute = 0;
}
if (!is_null($Job['Day']) && ($cron->day != $Job['Day'])) {
if ($cron->day > $Job['Day']) {
$cron->modify('+1 month');
}
$cron->day = $Job['Day'];
$cron->hour = 0;
$cron->minute = 0;
}
if (!is_null($Job['Month']) && ($cron->month != $Job['Month'])) {
if ($cron->month > $Job['Month']) {
$cron->modify('+1 year');
}
$cron->month = $Job['Month'];
$cron->day = 1;
$cron->hour = 0;
$cron->minute = 0;
}
$done = (is_null($Job['Minute']) || $Job['Minute'] == $cron->minute) &&
(is_null($Job['Hour']) || $Job['Hour'] == $cron->hour) &&
(is_null($Job['Day']) || $Job['Day'] == $cron->day) &&
(is_null($Job['Month']) || $Job['Month'] == $cron->month) &&
(is_null($Job['DOW']) || $Job['DOW'] == $cron->dow)?100:($done+1);
}
echo date('Y-m-d H:i:s', $cron->timestamp) . '<hr>';
Проверьте это :
Это может вычислить в следующий раз, когда запланированное задание, как предполагается, выполняется на основе данных определений крона.
Вот проект PHP, основанный на псевдокоде dlamblin.
Он может вычислить дату следующего выполнения выражения CRON, дату предыдущего выполнения выражения CRON и определить, соответствует ли выражение CRON заданному времени. Вы можете пропустить этот синтаксический анализатор выражения CRON полностью реализует CRON:
https://github.com/mtdowling/cron-expression
Использование (PHP 5.3 +):
<?php
// Works with predefined scheduling definitions
$cron = Cron\CronExpression::factory('@daily');
$cron->isDue();
$cron->getNextRunDate();
$cron->getPreviousRunDate();
// Works with complex expressions
$cron = Cron\CronExpression::factory('15 2,6-12 */15 1 2-5');
$cron->getNextRunDate();