Created
January 4, 2013 23:16
-
-
Save Shagshag/4458383 to your computer and use it in GitHub Desktop.
Check if a date is between two others with jockers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class checkRule | |
{ | |
/** | |
* check if $datetime is between the start date and end date of a rule | |
* | |
* $rule has this format : | |
* array( | |
* 'date_start' => 'YYYY-MM-DD HH:MM:SS', | |
* 'date_end' => 'YYYY-MM-DD HH:MM:SS', | |
* ); | |
* | |
* year and second of datetime are ignored | |
* 00 for month or day means * | |
* | |
* @param array $rule | |
* @param string/boolean $datetime when to valid the rule, if false current time is used | |
* @return boolean | |
*/ | |
function isRuleValid($rule, $datetime = false) | |
{ | |
$timetoCheck = $datetime ? strtotime($datetime) : time(); | |
list($date, $time) = explode(' ', $rule['date_start']); | |
list($start['year'], $start['month'], $start['day']) = explode('-', $date); | |
if ($start['month'] == 0) $start['month'] = null; | |
if ($start['day'] == 0) $start['day'] = null; | |
list($start['hour'], $start['minute'], $start['second']) = explode(':', $time); | |
list($date, $time) = explode(' ', $rule['date_end']); | |
list($end['year'], $end['month'], $end['day']) = explode('-', $date); | |
if ($end['month'] == 0) $end['month'] = null; | |
if ($end['day'] == 0) $end['day'] = null; | |
list($end['hour'], $end['minute'], $end['second']) = explode(':', $time); | |
$startPrev = $this->getPrevRun($timetoCheck, $start); | |
$startNext = $this->getNextRun($timetoCheck, $start); | |
$endPrev = $this->getPrevRun($timetoCheck, $end); | |
$endNext = $this->getNextRun($timetoCheck, $end); | |
return (($endPrev < $startPrev) && ($startNext > $endNext)); | |
} | |
/** | |
* Find the next time a job should be executed | |
* http://stackoverflow.com/questions/321494/calculate-when-a-cron-job-will-be-executed-then-next-time/ | |
* | |
* $job has this format : | |
* array( | |
* 'minute' => integer or null, | |
* 'hour' => integer or null, | |
* 'day' => integer or null, | |
* 'month' => integer or null | |
* ); | |
* null means '*' | |
* | |
* @param array $job | |
* @return int timestamp of the next execution | |
*/ | |
function getNextRun($time, $job) | |
{ | |
$job = $this->correctJob($job); | |
$cron = new simpleTimestamp($time); | |
$done = 0; | |
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['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) | |
? 100 : ($done + 1); | |
} | |
return $cron->timestamp; | |
} | |
/** | |
* Find the previous time a job should have been executed | |
* http://stackoverflow.com/questions/321494/calculate-when-a-cron-job-will-be-executed-then-next-time/ | |
* | |
* $job has this format : | |
* array( | |
* 'minute' => integer or null, | |
* 'hour' => integer or null, | |
* 'day' => integer or null, | |
* 'month' => integer or null | |
* ); | |
* null means '*' | |
* | |
* @param array $job | |
* @return int timestamp of the next execution | |
*/ | |
function getPrevRun($time, $job) | |
{ | |
$job = $this->correctJob($job); | |
$cron = new simpleTimestamp($time); | |
$done = 0; | |
while ($done < 100) | |
{ | |
if (!is_null($job['month']) && ($cron->month != $job['month'])) | |
{ | |
if ($cron->month < $job['month']) | |
{ | |
$cron->modify('-1 year'); | |
} | |
$cron->month = $job['month']; | |
$cron->day = (int)date('d', mktime(0, 0, 0, $cron->month + 1, 0, $cron->year)); | |
$cron->hour = 23; | |
$cron->minute = 59; | |
} | |
if (!is_null($job['day']) && ($cron->day != $job['day'])) | |
{ | |
if ($cron->day < $job['day']) | |
{ | |
$cron->modify('-1 month'); | |
} | |
$cron->day = $job['day']; | |
$cron->hour = 23; | |
$cron->minute = 59; | |
} | |
if (!is_null($job['hour']) && ($cron->hour != $job['hour'])) | |
{ | |
if ($cron->hour < $job['hour']) | |
{ | |
$cron->modify('-1 day'); | |
} | |
$cron->hour = $job['hour']; | |
$cron->minute = 59; | |
} | |
if (!is_null($job['minute']) && ($cron->minute != $job['minute'])) | |
{ | |
if ($cron->minute < $job['minute']) | |
{ | |
$cron->modify('-1 hour'); | |
} | |
$cron->minute = $job['minute']; | |
} | |
$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) ? 100 : ($done + 1); | |
} | |
return $cron->timestamp; | |
} | |
/** | |
* Correct invalid job | |
* For example 31/02 25:63 become 03/03 02:03 | |
* | |
* $job has this format : | |
* array( | |
* 'minute' => integer or null, | |
* 'hour' => integer or null, | |
* 'day' => integer or null, | |
* 'month' => integer or null | |
* ); | |
* null means '*' | |
* | |
* @param array $job | |
* @return array job valid | |
*/ | |
function correctJob($job) | |
{ | |
if ((int)$job['minute'] > 59) | |
{ | |
if ($job['hour'] !== null) $job['hour']+= (int)($job['minute'] / 60); | |
$job['minute']%= 60; | |
} | |
if ((int)$job['hour'] > 23) | |
{ | |
if ($job['day'] !== null) $job['day']+= (int)($job['hour'] / 24); | |
$job['hour']%= 24; | |
} | |
if ((int)$job['day'] > 29) | |
{ | |
if ($job['month'] !== null) | |
{ | |
$max = (int)date('d', mktime(0, 0, 0, $job['month'] + 1, 0)); | |
$job['month']+= (int)($job['day'] / $max); | |
$job['day'] = 1 + (int)($job['day'] % ($max + 1)); | |
} | |
else $job['hour']%= 31 + 1; | |
} | |
if ((int)$job['month'] > 11) | |
{ | |
$job['month'] = ($job['month'] % 12); | |
} | |
return $job; | |
} | |
} | |
/** | |
* Allows to use timestamp easily | |
* | |
* properties are: | |
* - second | |
* - minute | |
* - hour | |
* - day | |
* - month | |
* - year | |
* - timestamp | |
*/ | |
class simpleTimestamp | |
{ | |
private var $current_timestamp; | |
private static $dateComponent = array( | |
'second' => 's', | |
'minute' => 'i', | |
'hour' => 'G', | |
'day' => 'j', | |
'month' => 'n', | |
'year' => 'Y', | |
'timestamp' => 'U' | |
); | |
function __construct($timestamp = NULL) | |
{ | |
$this->current_timestamp = is_null($timestamp) ? time() : $timestamp; | |
} | |
function __set($var, $value) | |
{ | |
$components = array(); | |
list( $components['second'], | |
$components['minute'], | |
$components['hour'], | |
$components['day'], | |
$components['month'], | |
$components['year'] | |
) = explode(' ', date('s i G j n Y', $this->current_timestamp)); | |
switch ($var) | |
{ | |
case 'timestamp': | |
$this->current_timestamp = $value; | |
break; | |
default: | |
$components[$var] = $value; | |
$this->current_timestamp = mktime( | |
$components['hour'], | |
$components['minute'], | |
$components['second'], | |
$components['month'], | |
$components['day'], | |
$components['year'] | |
); | |
} | |
} | |
function __get($var) | |
{ | |
if (array_key_exists(self::$dateComponent, $var)) { | |
$result = date(self::$dateComponent[$var], $this->current_timestamp); | |
} else { | |
$result = false; | |
} | |
return $result; | |
} | |
/** | |
* Modify the time using strtotime | |
* http://php.net/strtotime | |
* | |
* @param string $how can by '+1 week 2 days 4 hours 2 seconds', '10 September 2000' or 'now' | |
*/ | |
function modify($how) | |
{ | |
return $this->current_timestamp = strtotime($how, $this->current_timestamp); | |
} | |
} | |
$tmp = new checkRule(); | |
$rule = array( | |
'date_start' => '0000-00-00 19:00:00', | |
'date_end' => '0000-00-00 18:00:00', | |
); | |
$tmp->isRuleValid($rule, '2012-05-04 15:00:00'); // true | |
$tmp->isRuleValid($rule, '2012-05-04 18:30:00'); // false | |
$rule = array( | |
'date_start' => '0000-03-20 0:00:00', | |
'date_end' => '0000-05-00 0:00:00', | |
); | |
$tmp->isRuleValid($rule, '2012-04-26 18:30:00'); // true | |
$tmp->isRuleValid($rule, '2012-05-04 18:30:00'); // false | |
$rule = array( | |
'date_start' => '0000-11-20 0:00:00', | |
'date_end' => '0000-02-00 0:00:00', | |
); | |
$tmp->isRuleValid($rule, '2012-01-01 00:00:00'); // true | |
$tmp->isRuleValid($rule, '2012-10-01 00:00:00'); // false | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment