1
0
mirror of https://github.com/rlanvin/php-rrule.git synced 2025-02-20 09:54:16 +01:00

Implementing HOURLY/MINUTELY/SECONDLY frequencies

Also adding more tests and fixing bugs
BYSETPOS + time is still broken!!
This commit is contained in:
rlanvin 2015-06-29 11:45:39 +03:00
parent fc13d3f8d7
commit 066a97d517
2 changed files with 1001 additions and 210 deletions

View File

@ -65,6 +65,19 @@ function is_leap_year($year)
return true;
}
/**
* Calculate the Greatest Common Divisor of a and b.
* Unless b==0, the result will have the same sign as b (so that when
* b is divided by it, the result comes out positive).
*/
function gcd($a, $b)
{
while ($b) {
list($a, $b) = array($b, $a % $b);
}
return $a;
}
/**
* Implementation of RRULE as defined by RFC 5545.
* Heavily based on python-dateutil/rrule
@ -396,8 +409,11 @@ class RRule implements \Iterator, \ArrayAccess
}
if ( not_empty($parts['BYSETPOS']) ) {
if ( ! (not_empty($parts['BYWEEKNO']) || not_empty($parts['BYYEARDAY']) || not_empty($parts['BYMONTHDAY']) || not_empty($parts['BYDAY']) || not_empty($parts['BYMONTH'])) ) {
throw new \InvalidArgumentException('The BYSETPOST rule part MUST only be used in conjunction with another BYxxx rule part.');
if ( ! (not_empty($parts['BYWEEKNO']) || not_empty($parts['BYYEARDAY'])
|| not_empty($parts['BYMONTHDAY']) || not_empty($parts['BYDAY'])
|| not_empty($parts['BYMONTH']) || not_empty($parts['BYHOUR'])
|| not_empty($parts['BYMINUTE']) || not_empty($parts['BYSECOND'])) ) {
throw new \InvalidArgumentException('The BYSETPOS rule part MUST only be used in conjunction with another BYxxx rule part.');
}
if ( ! is_array($parts['BYSETPOS']) ) {
@ -649,30 +665,50 @@ class RRule implements \Iterator, \ArrayAccess
break;
case self::MONTHLY:
// we need to count the number of months elapsed
$nb_months = (12 - $start_month) + 12*($year - $start_year - 1) + $month;
$diff = (12 - $start_month) + 12*($year - $start_year - 1) + $month;
if ( ($nb_months % $this->interval) !== 0 ) {
if ( ($diff % $this->interval) !== 0 ) {
return false;
}
break;
case self::WEEKLY:
// count nb of days and divide by 7 to get number of weeks
$nb_days = $date->diff($this->dtstart)->format('%a');
$nb_weeks = (int) ($nb_days/7);
if ( $nb_weeks % $this->interval !== 0 ) {
// we add some days to align dtstart with wkst
$diff = $date->diff($this->dtstart);
$diff = (int) (($diff->days + pymod($this->dtstart->format('N') - $this->wkst,7)) / 7);
if ( $diff % $this->interval !== 0 ) {
return false;
}
break;
case self::DAILY:
// count nb of days
$nb_days = $date->diff($this->dtstart)->format('%a');
if ( $nb_days % $this->interval !== 0 ) {
$diff = $date->diff($this->dtstart);
if ( $diff->days % $this->interval !== 0 ) {
return false;
}
break;
// XXX: I'm not sure the 3 formulas below take the DST into account...
case self::HOURLY:
$diff = $date->diff($this->dtstart);
$diff = $diff->h + $diff->days * 24;
if ( $diff % $this->interval !== 0 ) {
return false;
}
break;
case self::MINUTELY:
$diff = $date->diff($this->dtstart);
$diff = $diff->i + $diff->h * 60 + $diff->days * 1440;
if ( $diff % $this->interval !== 0 ) {
return false;
}
break;
case self::SECONDLY:
$diff = $date->diff($this->dtstart);
$diff = $diff->s + $diff->i * 60 + $diff->h * 3600 + $diff->days * 86400;
if ( $diff % $this->interval !== 0 ) {
return false;
}
break;
throw new \Exception('Unimplemented frequency');
}
@ -792,13 +828,11 @@ class RRule implements \Iterator, \ArrayAccess
return $set;
case self::DAILY:
$n = (int) date('z', mktime(0,0,0,$month,$day,$year));
return array($n);
case self::HOURLY:
case self::MINUTELY:
case self::SECONDLY:
throw new \Exception('Unimplemented frequency');
$n = (int) date('z', mktime(0,0,0,$month,$day,$year));
return array($n);
}
}
@ -863,7 +897,12 @@ class RRule implements \Iterator, \ArrayAccess
}
/**
* More magic
* More serious magic.
* This method calculates the yeardays corresponding to the week number
* (in the WEEKNO rule part).
* Because weeks can cross year boundaries (that is, week #1 can start the
* previous year, and week 52/53 can continue till the next year), the
* algorithm is quite long.
*/
protected function buildWeeknoMask($year, $month, $day, & $masks)
{
@ -972,10 +1011,82 @@ class RRule implements \Iterator, \ArrayAccess
}
}
/**
* Not sure what it does yet
*/
protected function getTimeSet($hour, $minute, $second)
{
// echo "getTimeSet($hour,$minute,$second)\n";
switch ( $this->freq ) {
case self::HOURLY:
$set = array();
foreach ( $this->byminute as $minute ) {
foreach ( $this->bysecond as $second ) {
// should we use another type?
$set[] = array($hour, $minute, $second);
}
}
// sort ?
return $set;
case self::MINUTELY:
$set = array();
foreach ( $this->bysecond as $second ) {
// should we use another type?
$set[] = array($hour, $minute, $second);
}
// sort ?
return $set;
case self::SECONDLY:
return array(array($hour, $minute, $second));
default:
throw new \LogicException('getTimeSet called with an invalid frequency');
}
}
/**
* This is the main method, where all of the magic happens.
*
* This method is a generator that works for PHP 5.3/5.4 (using static variables)
*
* The main idea is : a brute force made fast by not relying on date() functions
*
* There is one big loop that examines every interval of the given frequency
* (so every day, every week, every month or every year), constructs an
* array of all the yeardays of the interval (for daily frequencies, the array
* only has one element, for weekly 7, and so on), and then filters out any
* day that do no match BYXXX elements.
*
* The algorithm does not try to be "smart" in calculating the increment of
* the loop. That is, for a rule like "every day in January for 10 years"
* the algorithm will loop through every day of the year, each year, generating
* some 3650 iterations (+ some to account for the leap years).
* This is a bit counter-intuitive, as it is obvious that the loop could skip
* all the days in February till December since they are never going to match.
*
* Fortunately, this approach is still super fast because it doesn't rely
* on date() or DateTime functions, and instead does all the date operations
* manually, either arithmetically or using arrays as converters.
*
* Another quirk of this approach is that because the granularity is by day,
* higher frequencies (hourly, minutely and secondly) have to have
* their own special loops within the main loop.
* Moreover, at such frequencies, the brute-force approach starts to really
* suck. For example, a rule like
* "Every minute, every Jan 1st between 10:00 and 10:59, for 10 years"
* requires a tremendous amount of useless iterations to jump from Jan 1st 10:59
* at year 1 to Jan 1st 10.00 at year 2.
*
* In order to make a "smart jump", we would have to have a way to determine
* the gap between the next occurence arithmetically. I think that would require
* to analyze each "BYXXX" rule part that "Limit" the set (see the RFC page 43)
* at the given frequency. For example, a YEARLY frequency doesn't need "smart
* jump" at all; MONTHLY and WEEKLY frequencies only need to check BYMONTH;
* DAILY frequency needs to check BYMONTH, BYMONTHDAY and BYDAY, and so on.
* The check probably has to be done in reverse order, e.g. for DAILY frequencies
* attempt to jump to the next weekday (BYDAY) or next monthday (BYMONTHDAY)
* (I don't know yet which one first), and then if that results in a change of
* month, attempt to jump to the next BYMONTH, and so on.
*/
protected function iterate($reset = false)
{
@ -1004,19 +1115,25 @@ class RRule implements \Iterator, \ArrayAccess
// simply loop by adding +7 days. The Python lib does some
// calculation magic at the end of the loop (when incrementing)
// to realign on first pass.
$tmp = $this->dtstart->modify('-'.pymod($this->dtstart->format('N') - $this->wkst,7).'days');
list($year,$month,$day) = explode('-',$tmp->format('Y-n-j'));
$tmp = clone $this->dtstart;
$tmp = $tmp->modify('-'.pymod($this->dtstart->format('N') - $this->wkst,7).'days');
list($year,$month,$day,$hour,$minute,$second) = explode(' ',$tmp->format('Y n j G i s'));
unset($tmp);
}
else {
list($year,$month,$day) = explode('-',$this->dtstart->format('Y-n-j'));
list($year,$month,$day,$hour,$minute,$second) = explode(' ',$this->dtstart->format('Y n j G i s'));
}
// remove leading zeros
$minute = (int) $minute;
$second = (int) $second;
}
// todo, not sure when this should be rebuilt
// and not sure what this does anyway
if ( $timeset == null ) {
if ( $this->freq < self::HOURLY ) { // daily, weekly, monthly or yearly
if ( $this->freq < self::HOURLY ) {
// daily, weekly, monthly or yearly
// we don't need to calculate a new timeset
$timeset = $this->timeset;
}
else {
@ -1032,8 +1149,12 @@ class RRule implements \Iterator, \ArrayAccess
}
}
}
// echo json_encode($timeset),"\n";
// fgets(STDIN);
while (true) {
// while (true) {
$max_cycles = self::$REPEAT_CYCLES[$this->freq <= self::DAILY ? $this->freq : self::DAILY];
for ( $i = 0; $i < $max_cycles; $i++ ) {
// 1. get an array of all days in the next interval (day, month, week, etc.)
// we filter out from this array all days that do not match the BYXXX conditions
// to speed things up, we use days of the year (day numbers) instead of date
@ -1169,20 +1290,22 @@ class RRule implements \Iterator, \ArrayAccess
}
// 3. we reset the loop to the next interval
$current_set = null; // reset the loop
$days_increment = 0;
switch ( $this->freq ) {
case self::YEARLY:
// we do not care about $month or $day not existing, they are not used in yearly frequency
// we do not care about $month or $day not existing,
// they are not used in yearly frequency
$year = $year + $this->interval;
break;
case self::MONTHLY:
// we do not care about the day of the month not existing, it is not used in monthly frequency
// we do not care about the day of the month not existing
// it is not used in monthly frequency
$month = $month + $this->interval;
if ( $month > 12 ) {
$delta = (int) ($month / 12);
$div = (int) ($month / 12);
$mod = $month % 12;
$month = $mod;
$year = $year + $delta;
$year = $year + $div;
if ( $month == 0 ) {
$month = 12;
$year = $year - 1;
@ -1190,19 +1313,131 @@ class RRule implements \Iterator, \ArrayAccess
}
break;
case self::WEEKLY:
// here we take a little shortcut from the Python version, by using DateTime
list($year,$month,$day) = explode('-',date_create("$year-$month-$day")->modify('+'.($this->interval*7).'day')->format('Y-n-j'));
$days_increment = $this->interval*7;
break;
case self::DAILY:
// here we take a little shortcut from the Python version, by using DateTime
list($year,$month,$day) = explode('-',date_create("$year-$month-$day")->modify('+'.$this->interval.'day')->format('Y-n-j'));
$days_increment = $this->interval;
break;
// For the time frequencies, things are a little bit different.
// We could just add "$this->interval" hours, minutes or seconds
// to the current time, and go through the main loop again,
// but since the frequencies are so high and needs to much iteration
// it's actually a bit faster to have custom loops and only
// call the DateTime method at the very end.
case self::HOURLY:
if ( empty($current_set) ) {
// an empty set means that this day has been filtered out
// by one of the BYXXX rule. So there is no need to
// examine it any further, we know nothing is going to
// occur anyway.
// so we jump to one iteration right before next day
$hour += ((int) ((23 - $hour) / $this->interval)) * $this->interval;
}
$found = false;
for ( $j = 0; $j < self::$REPEAT_CYCLES[self::HOURLY]; $j++ ) {
$hour += $this->interval;
$div = (int) ($hour / 24);
$mod = $hour % 24;
if ( $div ) {
$hour = $mod;
$days_increment += $div;
}
if ( ! $this->byhour || in_array($hour, $this->byhour)) {
$found = true;
break;
}
}
if ( ! $found ) {
return null; // stop the iterator
}
$timeset = $this->getTimeSet($hour, $minute, $second);
break;
case self::MINUTELY:
if ( empty($current_set) ) {
$minute += ((int) ((1439 - ($hour*60+$minute)) / $this->interval)) * $this->interval;
}
$found = false;
for ( $j = 0; $j < self::$REPEAT_CYCLES[self::MINUTELY]; $j++ ) {
$minute += $this->interval;
$div = (int) ($minute / 60);
$mod = $minute % 60;
if ( $div ) {
$minute = $mod;
$hour += $div;
$div = (int) ($hour / 24);
$mod = $hour % 24;
if ( $div ) {
$hour = $mod;
$days_increment += $div;
}
}
if ( (! $this->byhour || in_array($hour, $this->byhour)) &&
(! $this->byminute || in_array($minute, $this->byminute)) ) {
$found = true;
break;
}
}
if ( ! $found ) {
return null; // stop the iterator
}
$timeset = $this->getTimeSet($hour, $minute, $second);
break;
case self::SECONDLY:
throw new \Exception('Unimplemented frequency');
if ( empty($current_set) ) {
$second += ((int) ((86399 - ($hour*3600 + $minute*60 + $second)) / $this->interval)) * $this->interval;
}
$found = false;
for ( $j = 0; $j < self::$REPEAT_CYCLES[self::SECONDLY]; $j++ ) {
$second += $this->interval;
$div = (int) ($second / 60);
$mod = $second % 60;
if ( $div ) {
$second = $mod;
$minute += $div;
$div = (int) ($minute / 60);
$mod = $minute % 60;
if ( $div ) {
$minute = $mod;
$hour += $div;
$div = (int) ($hour / 24);
$mod = $hour % 24;
if ( $div ) {
$hour = $mod;
$days_increment += $div;
}
}
}
if ( ( ! $this->byhour || in_array($hour, $this->byhour) )
&& ( ! $this->byminute || in_array($minute, $this->byminute) )
&& ( ! $this->bysecond || in_array($second, $this->bysecond) ) ) {
$found = true;
break;
}
}
if ( ! $found ) {
return null; // stop the iterator
}
$timeset = $this->getTimeSet($hour, $minute, $second);
break;
}
// here we take a little shortcut from the Python version, by using DateTime
if ( $days_increment ) {
list($year,$month,$day) = explode('-',date_create("$year-$month-$day")->modify("+ $days_increment days")->format('Y-n-j'));
}
$current_set = null; // reset the loop
}
return null; // stop the iterator
}
// constants
@ -1325,4 +1560,32 @@ class RRule implements \Iterator, \ArrayAccess
public static $LAST_DAY_OF_MONTH = array(
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
);
/**
* Maximum number of cycles after which a calendar repeats itself. This
* is used to detect infinite loop: if no occurrence has been found
* after this numbers of cycles, we can abort.
*
* The Gregorian calendar cycle repeat completely every 400 years
* (146,097 days or 20,871 weeks).
* A smaller cycle would be 28 years (1,461 weeks), but it only works
* if there is no dropped leap year in between.
* 2100 will be a dropped leap year, but I'm going to assume it's not
* going to be a problem anytime soon, so at the moment I use the 28 years
* cycle.
*/
public static $REPEAT_CYCLES = array(
// self::YEARLY => 400,
// self::MONTHLY => 4800,
// self::WEEKLY => 20871,
// self::DAILY => 146097, // that's a lot of cycles, it takes a few seconds to detect infinite loop
self::YEARLY => 28,
self::MONTHLY => 336,
self::WEEKLY => 1461,
self::DAILY => 10227,
self::HOURLY => 24,
self::MINUTELY => 1440,
self::SECONDLY => 86400 // that's a lot of cycles too
);
}

View File

@ -4,6 +4,9 @@ use RRule\RRule;
class RRuleTest extends PHPUnit_Framework_TestCase
{
/**
* These rules are invalid according to the RFC
*/
public function invalidRules()
{
return array(
@ -51,56 +54,98 @@ class RRuleTest extends PHPUnit_Framework_TestCase
new RRule($rule);
}
public function testIsLeapYear()
{
$this->assertFalse(\RRule\is_leap_year(1700));
$this->assertFalse(\RRule\is_leap_year(1800));
$this->assertFalse(\RRule\is_leap_year(1900));
$this->assertTrue(\RRule\is_leap_year(2000));
}
// date_create\((array(0-9)+), (array(0-9)+), (array(0-9)+)array( ,0-9\))+
/**
* YEARLY rules, mostly taken from Python test suite.
*/
public function yearlyRules()
{
return array(
array(array(),array(date_create('1997-09-02'),date_create('1998-09-02'), date_create('1999-09-02'))),
array(array('INTERVAL' => 2), array(date_create('1997-09-02'),date_create('1999-09-02'),date_create('2001-09-02'))),
array(array('DTSTART' => '2000-02-29'), array(date_create('2000-02-29'),date_create('2004-02-29'),date_create('2008-02-29'))),
array(array('BYMONTH' => array(1,3)), array(date_create('1998-01-02'),date_create('1998-03-02'),date_create('1999-01-02'))),
array(array('BYMONTHDAY' => array(1,3)), array(date_create('1997-09-03'),date_create('1997-10-01'),date_create('1997-10-03'))),
array(array('BYMONTH' => array(1,3), 'BYMONTHDAY' => array(5,7)), array(date_create('1998-01-05'),date_create('1998-01-07'),date_create('1998-03-05'))),
array(array('BYDAY' => array('TU','TH')), array(date_create('1997-09-02'),date_create('1997-09-04'),date_create('1997-09-09'))),
array(array('BYDAY' => array('SU')), array(date_create('1997-09-07'),date_create('1997-09-14'),date_create('1997-09-21'))),
array(array('BYDAY' => array('1TU','-1TH')), array(date_create('1997-12-25'),date_create('1998-01-06'),date_create('1998-12-31'))),
array(array('BYDAY' => array('3TU','-3TH')), array(date_create('1997-12-11'),date_create('1998-01-20'),date_create('1998-12-17'))),
array(array('BYMONTH' => array(1,3), 'BYDAY' => array('TU','TH')), array(date_create('1998-01-01'),date_create('1998-01-06'),date_create('1998-01-08'))),
array(array('BYMONTH' => array(1,3), 'BYDAY' => array('1TU','-1TH')), array(date_create('1998-01-06'),date_create('1998-01-29'),date_create('1998-03-03'))),
array(array(),array(
date_create('1997-09-02'),date_create('1998-09-02'), date_create('1999-09-02'))),
array(array('INTERVAL' => 2), array(
date_create('1997-09-02'),date_create('1999-09-02'),date_create('2001-09-02'))),
array(array('DTSTART' => '2000-02-29'), array(
date_create('2000-02-29'),date_create('2004-02-29'),date_create('2008-02-29'))),
array(array('BYMONTH' => array(1,3)), array(
date_create('1998-01-02'),date_create('1998-03-02'),date_create('1999-01-02'))),
array(array('BYMONTHDAY' => array(1,3)), array(
date_create('1997-09-03'),date_create('1997-10-01'),date_create('1997-10-03'))),
array(array('BYMONTH' => array(1,3), 'BYMONTHDAY' => array(5,7)), array(
date_create('1998-01-05'),date_create('1998-01-07'),date_create('1998-03-05'))),
array(array('BYDAY' => array('TU','TH')), array(
date_create('1997-09-02'),date_create('1997-09-04'),date_create('1997-09-09'))),
array(array('BYDAY' => array('SU')), array(
date_create('1997-09-07'),date_create('1997-09-14'),date_create('1997-09-21'))),
array(array('BYDAY' => array('1TU','-1TH')), array(
date_create('1997-12-25'),date_create('1998-01-06'),date_create('1998-12-31'))),
array(array('BYDAY' => array('3TU','-3TH')), array(
date_create('1997-12-11'),date_create('1998-01-20'),date_create('1998-12-17'))),
array(array('BYMONTH' => array(1,3), 'BYDAY' => array('TU','TH')), array(
date_create('1998-01-01'),date_create('1998-01-06'),date_create('1998-01-08'))),
array(array('BYMONTH' => array(1,3), 'BYDAY' => array('1TU','-1TH')), array(
date_create('1998-01-06'),date_create('1998-01-29'),date_create('1998-03-03'))),
// This is interesting because the TH(-3) ends up before the TU(3).
array(array('BYMONTH' => array(1,3), 'BYDAY' => array('3TU','-3TH')), array(date_create('1998-01-15'),date_create('1998-01-20'),date_create('1998-03-12'))),
array(array('BYMONTHDAY' => array(1,3), 'BYDAY' => array('TU','TH')), array(date_create('1998-01-01'),date_create('1998-02-03'),date_create('1998-03-03'))),
array(array('BYMONTHDAY' => array(1,3), 'BYDAY' => array('TU','TH'), 'BYMONTH' => array(1,3)), array(date_create('1998-01-01'),date_create('1998-03-03'),date_create('2001-03-01'))),
array(array('BYYEARDAY' => array(1,100,200,365), 'COUNT' => 4), array(date_create('1997-12-31'),date_create('1998-01-01'),date_create('1998-04-10'), date_create('1998-07-19'))),
array(array('BYYEARDAY' => array(-365, -266, -166, -1), 'COUNT' => 4), array(date_create('1997-12-31'),date_create('1998-01-01'),date_create('1998-04-10'), date_create('1998-07-19'))),
array(array('BYYEARDAY' => array(1,100,200,365), 'BYMONTH' => array(4,7), 'COUNT' => 4), array(date_create('1998-04-10'),date_create('1998-07-19'),date_create('1999-04-10'), date_create('1999-07-19'))),
array(array('BYYEARDAY' => array(-365, -266, -166, -1), 'BYMONTH' => array(4,7), 'COUNT' => 4), array(date_create('1998-04-10'),date_create('1998-07-19'),date_create('1999-04-10'), date_create('1999-07-19'))),
array(array('BYWEEKNO' => 20),array(date_create('1998-05-11'),date_create('1998-05-12'),date_create('1998-05-13'))),
array(array('BYMONTH' => array(1,3), 'BYDAY' => array('3TU','-3TH')), array(
date_create('1998-01-15'),date_create('1998-01-20'),date_create('1998-03-12'))),
array(array('BYMONTHDAY' => array(1,3), 'BYDAY' => array('TU','TH')), array(
date_create('1998-01-01'),date_create('1998-02-03'),date_create('1998-03-03'))),
array(array('BYMONTHDAY' => array(1,3), 'BYDAY' => array('TU','TH'), 'BYMONTH' => array(1,3)), array(
date_create('1998-01-01'),date_create('1998-03-03'),date_create('2001-03-01'))),
array(array('BYYEARDAY' => array(1,100,200,365), 'COUNT' => 4), array(
date_create('1997-12-31'),date_create('1998-01-01'),date_create('1998-04-10'), date_create('1998-07-19'))),
array(array('BYYEARDAY' => array(-365, -266, -166, -1), 'COUNT' => 4), array(
date_create('1997-12-31'),date_create('1998-01-01'),date_create('1998-04-10'), date_create('1998-07-19'))),
array(array('BYYEARDAY' => array(1,100,200,365), 'BYMONTH' => array(4,7), 'COUNT' => 4), array(
date_create('1998-04-10'),date_create('1998-07-19'),date_create('1999-04-10'), date_create('1999-07-19'))),
array(array('BYYEARDAY' => array(-365, -266, -166, -1), 'BYMONTH' => array(4,7), 'COUNT' => 4), array(
date_create('1998-04-10'),date_create('1998-07-19'),date_create('1999-04-10'), date_create('1999-07-19'))),
array(array('BYWEEKNO' => 20),array(
date_create('1998-05-11'),date_create('1998-05-12'),date_create('1998-05-13'))),
// That's a nice one. The first days of week number one may be in the last year.
array(array('BYWEEKNO' => 1, 'BYDAY' => 'MO'), array(date_create('1997-12-29'), date_create('1999-01-04'), date_create('2000-01-03'))),
array(array('BYWEEKNO' => 1, 'BYDAY' => 'MO'), array(
date_create('1997-12-29'), date_create('1999-01-04'), date_create('2000-01-03'))),
// Another nice test. The last days of week number 52/53 may be in the next year.
array(array('BYWEEKNO' => 52, 'BYDAY' => 'SU'), array(date_create('1997-12-28'), date_create('1998-12-27'), date_create('2000-01-02'))),
array(array('BYWEEKNO' => -1, 'BYDAY' => 'SU'), array(date_create('1997-12-28'), date_create('1999-01-03'), date_create('2000-01-02'))),
array(array('BYWEEKNO' => 53, 'BYDAY' => 'MO'), array(date_create('1998-12-28'), date_create('2004-12-27'), date_create('2009-12-28'))),
array(array('BYWEEKNO' => 52, 'BYDAY' => 'SU'), array(
date_create('1997-12-28'), date_create('1998-12-27'), date_create('2000-01-02'))),
array(array('BYWEEKNO' => -1, 'BYDAY' => 'SU'), array(
date_create('1997-12-28'), date_create('1999-01-03'), date_create('2000-01-02'))),
array(array('BYWEEKNO' => 53, 'BYDAY' => 'MO'), array(
date_create('1998-12-28'), date_create('2004-12-27'), date_create('2009-12-28'))),
// FIXME (time part missing)
// array(array('BYHOUR' => array(6, 18)), array(date_create('1997-09-02'),date_create('1998-09-02'),date_create('1998-09-02'))),
// array(array('BYMINUTE'=> array(6, 18)), array('1997-09-02', '1997-09-02', '1998-09-02')),
// array(array('BYSECOND' => array(6, 18)), array('1997-09-02', '1997-09-02', '1998-09-02')),
// array(array('BYHOUR' => array(6, 18), 'BYMINUTE' => array(6, 18)), array('1997-09-02','1997-09-02','1998-09-02')),
// array(array('BYHOUR' => array(6, 18), 'BYSECOND' => array(6, 18)), array('1997-09-02','1997-09-02','1998-09-02')),
// array(array('BYMINUTE' => array(6, 18), 'BYSECOND' => array(6, 18)), array('1997-09-02','1997-09-02','1997-09-02')),
// array(array('BYHOUR'=>array(6, 18),'BYMINUTE'=>array(6, 18),'BYSECOND'=>array(6, 18)),array('1997-09-02','1997-09-02','1997-09-02')),
// array(array('BYMONTHDAY'=>15,'BYHOUR'=>array(6, 18),'BYSETPOS'=>array(3, -3),array(date_create('1997-11-15'),date_create('1998-02-15'),date_create('1998-11-15')))
// TODO BYSETPOS
array(array('BYHOUR' => array(6, 18)),array(
date_create('1997-09-02 06:00:00'),
date_create('1997-09-02 18:00:00'),
date_create('1998-09-02 06:00:00'))),
array(array('BYMINUTE'=> array(15, 30)), array(
date_create('1997-09-02 00:15:00'),
date_create('1997-09-02 00:30:00'),
date_create('1998-09-02 00:15:00'))),
array(array('BYSECOND' => array(10, 20)), array(
date_create('1997-09-02 00:00:10'),
date_create('1997-09-02 00:00:20'),
date_create('1998-09-02 00:00:10'))),
array(array('BYHOUR' => array(6, 18), 'BYMINUTE' => array(15, 30)), array(
date_create('1997-09-02 06:15:00'),
date_create('1997-09-02 06:30:00'),
date_create('1997-09-02 18:15:00'))),
array(array('BYHOUR' => array(6, 18), 'BYSECOND' => array(10, 20)), array(
date_create('1997-09-02 06:00:10'),
date_create('1997-09-02 06:00:20'),
date_create('1997-09-02 18:00:10'))),
array(array('BYMINUTE' => array(15, 30), 'BYSECOND' => array(10, 20)), array(
date_create('1997-09-02 00:15:10'),
date_create('1997-09-02 00:15:20'),
date_create('1997-09-02 00:30:10'))),
array(array('BYHOUR'=>array(6, 18),'BYMINUTE'=>array(15, 30),'BYSECOND'=>array(10, 20)),array(
date_create('1997-09-02 06:15:10'),
date_create('1997-09-02 06:15:20'),
date_create('1997-09-02 06:30:10'))),
// array(array('BYMONTHDAY'=>15,'BYHOUR'=>array(6, 18),'BYSETPOS'=>array(3, -3)),array(
// date_create('1997-11-15 18:00:00'),
// date_create('1998-02-15 06:00:00'),
// date_create('1998-11-15 18:00:00')))
);
}
@ -121,34 +166,62 @@ class RRuleTest extends PHPUnit_Framework_TestCase
}
/**
* MONTHY rules, mostly taken from the Python test suite
*/
public function monthlyRules()
{
return array(
array(array(),array(date_create('1997-09-02'),date_create('1997-10-02'),date_create('1997-11-02'))),
array(array('INTERVAL'=>2),array(date_create('1997-09-02'),date_create('1997-11-02'),date_create('1998-01-02'))),
array(array('INTERVAL'=>18),array(date_create('1997-09-02'),date_create('1999-03-02'),date_create('2000-09-02'))),
array(array('BYMONTH' => array(1, 3)),array(date_create('1998-01-02'),date_create('1998-03-02'),date_create('1999-01-02'))),
array(array('BYMONTHDAY' => array(1, 3)),array(date_create('1997-09-03'),date_create('1997-10-01'),date_create('1997-10-03'))),
array(array('BYMONTHDAY' => array(5, 7), 'BYMONTH' => array(1, 3)), array(date_create('1998-01-05'), date_create('1998-01-07'), date_create('1998-03-05'))),
array(array('BYDAY' => array('TU', 'TH')), array(date_create('1997-09-02'),date_create('1997-09-04'),date_create('1997-09-09'))),
array(array(),array(
date_create('1997-09-02'),date_create('1997-10-02'),date_create('1997-11-02'))),
array(array('INTERVAL'=>2),array(
date_create('1997-09-02'),date_create('1997-11-02'),date_create('1998-01-02'))),
array(array('INTERVAL'=>18),array(
date_create('1997-09-02'),date_create('1999-03-02'),date_create('2000-09-02'))),
array(array('BYMONTH' => array(1, 3)),array(
date_create('1998-01-02'),date_create('1998-03-02'),date_create('1999-01-02'))),
array(array('BYMONTHDAY' => array(1, 3)),array(
date_create('1997-09-03'),date_create('1997-10-01'),date_create('1997-10-03'))),
array(array('BYMONTHDAY' => array(5, 7), 'BYMONTH' => array(1, 3)), array(
date_create('1998-01-05'), date_create('1998-01-07'), date_create('1998-03-05'))),
array(array('BYDAY' => array('TU', 'TH')), array(
date_create('1997-09-02'),date_create('1997-09-04'),date_create('1997-09-09'))),
// Third Monday of the month
array(array('BYDAY' => '3MO'),array(date_create('1997-09-15'),date_create('1997-10-20'),date_create('1997-11-17'))),
array(array('BYDAY' => '1TU,-1TH'),array(date_create('1997-09-02'),date_create('1997-09-25'),date_create('1997-10-07'))),
array(array('BYDAY' => '3TU,-3TH'),array(date_create('1997-09-11'),date_create('1997-09-16'),date_create('1997-10-16'))),
array(array('BYDAY' => 'TU,TH', 'BYMONTH' => array(1, 3)),array(date_create('1998-01-01'),date_create('1998-01-06'),date_create('1998-01-08'))),
array(array('BYMONTH' => array(1, 3), 'BYDAY' => '1TU, -1TH'),array(date_create('1998-01-06'),date_create('1998-01-29'),date_create('1998-03-03'))),
array(array('BYMONTH' => array(1, 3), 'BYDAY' => '3TU, -3TH'),array(date_create('1998-01-15'),date_create('1998-01-20'),date_create('1998-03-12'))),
array(array('BYMONTHDAY' => array(1, 3), 'BYDAY' => array('TU', 'TH')), array(date_create('1998-01-01'),date_create('1998-02-03'),date_create('1998-03-03'))),
array(array('BYMONTH' => array(1, 3), 'BYMONTHDAY' => array(1, 3), 'BYDAY' => array('TU', 'TH')),array(date_create('1998-01-01'),date_create('1998-03-03'),date_create('2001-03-01'))),
array(array('BYDAY' => '3MO'),array(
date_create('1997-09-15'),date_create('1997-10-20'),date_create('1997-11-17'))),
array(array('BYDAY' => '1TU,-1TH'),array(
date_create('1997-09-02'),date_create('1997-09-25'),date_create('1997-10-07'))),
array(array('BYDAY' => '3TU,-3TH'),array(
date_create('1997-09-11'),date_create('1997-09-16'),date_create('1997-10-16'))),
array(array('BYDAY' => 'TU,TH', 'BYMONTH' => array(1, 3)),array(
date_create('1998-01-01'),date_create('1998-01-06'),date_create('1998-01-08'))),
array(array('BYMONTH' => array(1, 3), 'BYDAY' => '1TU, -1TH'),array(
date_create('1998-01-06'),date_create('1998-01-29'),date_create('1998-03-03'))),
array(array('BYMONTH' => array(1, 3), 'BYDAY' => '3TU, -3TH'),array(
date_create('1998-01-15'),date_create('1998-01-20'),date_create('1998-03-12'))),
array(array('BYMONTHDAY' => array(1, 3), 'BYDAY' => array('TU', 'TH')), array(
date_create('1998-01-01'),date_create('1998-02-03'),date_create('1998-03-03'))),
array(array('BYMONTH' => array(1, 3), 'BYMONTHDAY' => array(1, 3), 'BYDAY' => array('TU', 'TH')),array(
date_create('1998-01-01'),date_create('1998-03-03'),date_create('2001-03-01'))),
// array(array('BYHOUR'=> array(6, 18),array('1997-09-02',date_create('1997-10-02'),date_create('1997-10-02'))),
// array(array('BYMINUTE'=> array(6, 18),array('1997-09-02','1997-09-02',date_create('1997-10-02'))),
// array(array('BYSECOND' => array(6, 18),array('1997-09-02','1997-09-02',date_create('1997-10-02'))),
// array(array('BYHOUR'=>array(6, 18),'BYMINUTE'=>array(6, 18)),array('1997-09-02','1997-09-02',date_create('1997-10-02'))),
// array(array('BYHOUR'=>array(6, 18),'BYSECOND'=>array(6, 18)),array('1997-09-02','1997-09-02',date_create('1997-10-02'))),
// array(array('BYMINUTE'=>array(6, 18),'BYSECOND'=>array(6, 18)),array('1997-09-02','1997-09-02','1997-09-02')),
// array(array('BYHOUR'=>array(6, 18),'BYMINUTE'=>array(6, 18),'BYSECOND'=>array(6, 18)),array('1997-09-02','1997-09-02','1997-09-02')),
// array(array('BYMONTHDAY'=>array(13, 17),'BYHOUR'=>array(6, 18),'BYSETPOS'=>array(3, -3)),array(date_create('1997-09-13'),date_create('1997-09-17'),date_create('1997-10-13')))
// TODO BYSETPOS
array(array('BYHOUR'=> array(6, 18)),array(
date_create('1997-09-02 06:00:00'),date_create('1997-09-02 18:00:00'),date_create('1997-10-02 06:00:00'))),
array(array('BYMINUTE'=> array(6, 18)),array(
date_create('1997-09-02 00:06:00'),date_create('1997-09-02 00:18:00'),date_create('1997-10-02 00:06:00'))),
array(array('BYSECOND' => array(6, 18)),array(
date_create('1997-09-02 00:00:06'),date_create('1997-09-02 00:00:18'),date_create('1997-10-02 00:00:06'))),
array(array('BYHOUR'=>array(6, 18),'BYMINUTE'=>array(6, 18)),array(
date_create('1997-09-02 06:06:00'),date_create('1997-09-02 06:18:00'),date_create('1997-09-02 18:06:00'))),
array(array('BYHOUR'=>array(6, 18),'BYSECOND'=>array(6, 18)),array(
date_create('1997-09-02 06:00:06'),date_create('1997-09-02 06:00:18'),date_create('1997-09-02 18:00:06'))),
array(array('BYMINUTE'=>array(6, 18),'BYSECOND'=>array(6, 18)),array(
date_create('1997-09-02 00:06:06'),date_create('1997-09-02 00:06:18'),date_create('1997-09-02 00:18:06'))),
array(array('BYHOUR'=>array(6, 18),'BYMINUTE'=>array(6, 18),'BYSECOND'=>array(6, 18)),array(
date_create('1997-09-02 06:06:06'),date_create('1997-09-02 06:06:18'),date_create('1997-09-02 06:18:06'))),
// array(array('BYMONTHDAY'=>array(13, 17),'BYHOUR'=>array(6, 18),'BYSETPOS'=>array(3, -3)),array(
// date_create('1997-09-13 06:00'),date_create('1997-09-17'),date_create('1997-10-13')))
);
}
@ -168,28 +241,45 @@ class RRuleTest extends PHPUnit_Framework_TestCase
}
}
/**
* WEEKLY rules, mostly taken from the Python test suite
*/
public function weeklyRules()
{
return array(
array(array(),array(date_create('1997-09-02'), date_create('1997-09-09'), date_create('1997-09-16'))),
array(array('interval'=>2),array(date_create('1997-09-02'),date_create('1997-09-16'),date_create('1997-09-30'))),
array(array('interval'=>20),array(date_create('1997-09-02'),date_create('1998-01-20'),date_create('1998-06-09'))),
array(array('bymonth'=>array(1, 3)),array(date_create('1998-01-06'),date_create('1998-01-13'),date_create('1998-01-20'))),
array(array('byday'=> array('TU', 'TH')),array(date_create('1997-09-02'), date_create('1997-09-04'), date_create('1997-09-09'))),
array(array(),array(
date_create('1997-09-02'), date_create('1997-09-09'), date_create('1997-09-16'))),
array(array('interval'=>2),array(
date_create('1997-09-02'),date_create('1997-09-16'),date_create('1997-09-30'))),
array(array('interval'=>20),array(
date_create('1997-09-02'),date_create('1998-01-20'),date_create('1998-06-09'))),
array(array('bymonth'=>array(1, 3)),array(
date_create('1998-01-06'),date_create('1998-01-13'),date_create('1998-01-20'))),
array(array('byday'=> array('TU', 'TH')),array(
date_create('1997-09-02'), date_create('1997-09-04'), date_create('1997-09-09'))),
# This test is interesting, because it crosses the year
# boundary in a weekly period to find day '1' as a
# valid recurrence.
array(array('bymonth'=>array(1, 3),'byday'=>array('TU', 'TH')),array(date_create('1998-01-01'), date_create('1998-01-06'), date_create('1998-01-08'))),
array(array('bymonth'=>array(1, 3),'byday'=>array('TU', 'TH')),array(
date_create('1998-01-01'), date_create('1998-01-06'), date_create('1998-01-08'))),
// array(array('byhour'=>array(6, 18)),array(date_create('1997-09-02'),date_create('1997-09-09'),date_create('1997-09-09'))),
// array(array('byminute'=>array(6, 18)),array(date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-09'))),
// array(array('bysecond'=> array(6, 18)),array(date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-09'))),
// array(array('byhour'=> array(6, 18),'byminute'=>array(6, 18)),array(date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-09'))),
// array(array('byhour'=>array(6, 18),'bysecond'=>array(6, 18)),array(date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-09'))),
// array(array('byminute'=>array(6, 18),'bysecond'=>array(6, 18)),array(date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-02'))),
// array(array('byhour'=>array(6, 18),'byminute'=>array(6, 18),'bysecond'=>array(6, 18)),array(date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-02'))),
// array(array('byday'=>array('TU', 'TH'),'byhour'=>array(6, 18),'bysetpos'=>array(3, -3)),array(date_create('1997-09-02'),date_create('1997-09-04'),date_create('1997-09-09')))
array(array('byhour'=>array(6, 18)),array(
date_create('1997-09-02 06:00:00'),date_create('1997-09-02 18:00:00'),date_create('1997-09-09 06:00:00'))),
array(array('byminute'=>array(6, 18)),array(
date_create('1997-09-02 00:06:00'),date_create('1997-09-02 00:18:00'),date_create('1997-09-09 00:06:00'))),
array(array('bysecond'=> array(6, 18)),array(
date_create('1997-09-02 00:00:06'),date_create('1997-09-02 00:00:18'),date_create('1997-09-09 00:00:06'))),
array(array('byhour'=> array(6, 18),'byminute'=>array(6, 18)),array(
date_create('1997-09-02 06:06:00'),date_create('1997-09-02 06:18:00'),date_create('1997-09-02 18:06:00'))),
// array(array('byhour'=>array(6, 18),'bysecond'=>array(6, 18)),array(
// date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-09'))),
// array(array('byminute'=>array(6, 18),'bysecond'=>array(6, 18)),array(
// date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-02'))),
// array(array('byhour'=>array(6, 18),'byminute'=>array(6, 18),'bysecond'=>array(6, 18)),array(
// date_create('1997-09-02'),date_create('1997-09-02'),date_create('1997-09-02'))),
// array(array('byday'=>array('TU', 'TH'),'byhour'=>array(6, 18),'bysetpos'=>array(3, -3)),array(
// date_create('1997-09-02'),date_create('1997-09-04'),date_create('1997-09-09')))
);
}
/**
@ -208,28 +298,51 @@ class RRuleTest extends PHPUnit_Framework_TestCase
}
}
/**
* DAILY rules, mostly taken from the Python test suite
*/
public function dailyRules()
{
return array(
array(array(), array(date_create('1997-09-02'),date_create('1997-09-03'),date_create('1997-09-04'))),
array(array('interval'=>2),array(date_create('1997-09-02'), date_create('1997-09-04'), date_create('1997-09-06'))),
array(array('interval'=>92),array(date_create('1997-09-02'), date_create('1997-12-03'), date_create('1998-03-05'))),
array(array('bymonth'=>array(1, 3)),array(date_create('1998-01-01'), date_create('1998-01-02'), date_create('1998-01-03'))),
array(array('bymonthday'=>array(1, 3)),array(date_create('1997-09-03'), date_create('1997-10-01'), date_create('1997-10-03'))),
array(array('bymonth'=>array(1, 3),'bymonthday'=>array(5, 7)),array(date_create('1998-01-05'), date_create('1998-01-07'), date_create('1998-03-05'))),
array(array('byday'=>array('TU', 'TH')),array(date_create('1997-09-02'), date_create('1997-09-04'), date_create('1997-09-09'))),
array(array('bymonth'=> array(1, 3), 'byday'=> array('TU', 'TH')),array(date_create('1998-01-01'), date_create('1998-01-06'), date_create('1998-01-08'))),
array(array('bymonthday'=> array(1, 3), 'byday'=>array('TU', 'TH')),array(date_create('1998-01-01'), date_create('1998-02-03'), date_create('1998-03-03'))),
array(array('bymonth'=>array(1, 3),'bymonthday'=>array(1, 3),'byday'=>array('TU', 'TH')),array(date_create('1998-01-01'), date_create('1998-03-03'), date_create('2001-03-01'))),
// array(array('count'=>4,'byyearday'=>array(1, 100, 200, 365)),array(date_create('1997-12-31'), date_create('1998-01-01'), date_create('1998-04-10'), date_create('1998-07-19'))),
// array(array('count'=>4,'byyearday'=>array(-365, -266, -166, -1)),array(date_create('1997-12-31'), date_create('1998-01-01'), date_create('1998-04-10'), date_create('1998-07-19'))),
// array(array('count'=>4, 'bymonth'=>array(1, 7),'byyearday'=>array(1, 100, 200, 365)),array(date_create('1998-01-01'),date_create('1998-07-19'),date_create('1999-01-01'),date_create('1999-07-19'))),
// array(array('count'=>4, 'bymonth' => array(1, 7), 'byyearday' => array(-365, -266, -166, -1)),array(date_create('1998-01-01'), date_create('1998-07-19'), date_create('1999-01-01'), date_create('1999-07-19'))),
// array(array('byweekno' => 20), array(date_create('1998-05-11'), date_create('1998-05-12'), date_create('1998-05-13'))),
// array(array('byweekno' => 1, 'byday' => 'MO'),array(date_create('1997-12-29'),date_create('1999-01-04'),date_create('2000-01-03'))),
// array(array('byweekno' => 52, 'byday' => 'SU'), array(date_create('1997-12-28'), date_create('1998-12-27'), date_create('2000-01-02'))),
// array(array('byweekno' => -1, 'byday' => 'SU'),array(date_create('1997-12-28'),date_create('1999-01-03'),date_create('2000-01-02'))),
// array(array('byweekno'=>53,'byday'=>'MO'),array(date_create('1998-12-28'), date_create('2004-12-27'), date_create('2009-12-28')))
array(array(), array(
date_create('1997-09-02'),date_create('1997-09-03'),date_create('1997-09-04'))),
array(array('interval'=>2),array(
date_create('1997-09-02'), date_create('1997-09-04'), date_create('1997-09-06'))),
array(array('interval'=>92),array(
date_create('1997-09-02'), date_create('1997-12-03'), date_create('1998-03-05'))),
array(array('bymonth'=>array(1, 3)),array(
date_create('1998-01-01'), date_create('1998-01-02'), date_create('1998-01-03'))),
array(array('bymonthday'=>array(1, 3)),array(
date_create('1997-09-03'), date_create('1997-10-01'), date_create('1997-10-03'))),
array(array('bymonth'=>array(1, 3),'bymonthday'=>array(5, 7)),array(
date_create('1998-01-05'), date_create('1998-01-07'), date_create('1998-03-05'))),
array(array('byday'=>array('TU', 'TH')),array(
date_create('1997-09-02'), date_create('1997-09-04'), date_create('1997-09-09'))),
array(array('bymonth'=> array(1, 3), 'byday'=> array('TU', 'TH')),array(
date_create('1998-01-01'), date_create('1998-01-06'), date_create('1998-01-08'))),
array(array('bymonthday'=> array(1, 3), 'byday'=>array('TU', 'TH')),array(
date_create('1998-01-01'), date_create('1998-02-03'), date_create('1998-03-03'))),
array(array('bymonth'=>array(1, 3),'bymonthday'=>array(1, 3),'byday'=>array('TU', 'TH')),array(
date_create('1998-01-01'), date_create('1998-03-03'), date_create('2001-03-01'))),
// TODO BYSETPOS
array(array('BYHOUR'=> array(6, 18)),array(
date_create('1997-09-02 06:00:00'),date_create('1997-09-02 18:00:00'),date_create('1997-09-03 06:00:00'))),
array(array('BYMINUTE'=> array(6, 18)),array(
date_create('1997-09-02 00:06:00'),date_create('1997-09-02 00:18:00'),date_create('1997-09-03 00:06:00'))),
array(array('BYSECOND' => array(6, 18)),array(
date_create('1997-09-02 00:00:06'),date_create('1997-09-02 00:00:18'),date_create('1997-09-03 00:00:06'))),
array(array('BYHOUR'=>array(6, 18),'BYMINUTE'=>array(6, 18)),array(
date_create('1997-09-02 06:06:00'),date_create('1997-09-02 06:18:00'),date_create('1997-09-02 18:06:00'))),
array(array('BYHOUR'=>array(6, 18),'BYSECOND'=>array(6, 18)),array(
date_create('1997-09-02 06:00:06'),date_create('1997-09-02 06:00:18'),date_create('1997-09-02 18:00:06'))),
array(array('BYMINUTE'=>array(6, 18),'BYSECOND'=>array(6, 18)),array(
date_create('1997-09-02 00:06:06'),date_create('1997-09-02 00:06:18'),date_create('1997-09-02 00:18:06'))),
array(array('BYHOUR'=>array(6, 18),'BYMINUTE'=>array(6, 18),'BYSECOND'=>array(6, 18)),array(
date_create('1997-09-02 06:06:06'),date_create('1997-09-02 06:06:18'),date_create('1997-09-02 06:18:06'))),
// array(array('BYMONTHDAY'=>array(13, 17),'BYHOUR'=>array(6, 18),'BYSETPOS'=>array(3, -3)),array(
// date_create('1997-09-13 06:00'),date_create('1997-09-17'),date_create('1997-10-13')))
);
}
/**
@ -248,85 +361,354 @@ class RRuleTest extends PHPUnit_Framework_TestCase
}
}
/**
* HOURLY rules, mostly taken from the Python test suite
*/
public function hourlyRules()
{
return array(
array(array(), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 10:00:00'),
date_create('1997-09-02 11:00:00'))),
array(array('interval' => 2), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 11:00:00'),
date_create('1997-09-02 13:00:00'))),
array(array('interval' => 769), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-10-04 10:00:00'),
date_create('1997-11-05 11:00:00'))),
array(array('bymonth' => '1, 3'), array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 01:00:00'),
date_create('1998-01-01 02:00:00'))),
array(array('bymonthday'=>'1, 3'), array(
date_create('1997-09-03 00:00:00'),
date_create('1997-09-03 01:00:00'),
date_create('1997-09-03 02:00:00'))),
array(array('bymonth'=>'1, 3','bymonthday'=>'5, 7'),array(
date_create('1998-01-05 00:00'),
date_create('1998-01-05 01:00'),
date_create('1998-01-05 02:00'))),
array(array('byday'=>'TU, TH'), array(
date_create('1997-09-02 09:00'),
date_create('1997-09-02 10:00'),
date_create('1997-09-02 11:00'))),
array(array('bymonth'=> '1, 3', 'byday' => 'TU, TH'), array(
date_create('1998-01-01 00:00'),
date_create('1998-01-01 01:00'),
date_create('1998-01-01 02:00'))),
array(array('bymonthday'=>'1, 3','byday'=>'TU, TH'), array(
date_create('1998-01-01 00:00'),
date_create('1998-01-01 01:00'),
date_create('1998-01-01 02:00'))),
array(array('bymonth'=> '1, 3','bymonthday'=>'1, 3','byday'=>'TU, TH'), array(
date_create('1998-01-01 00:00'),
date_create('1998-01-01 01:00'),
date_create('1998-01-01 02:00'))),
array(array('count'=>4,'byyearday'=>'1, 100, 200, 365'), array(
date_create('1997-12-31 00:00'),
date_create('1997-12-31 01:00'),
date_create('1997-12-31 02:00'),
date_create('1997-12-31 03:00'))),
array(array('count'=>4,'byyearday'=>'-365, -266, -166, -1'), array(
date_create('1997-12-31 00:00'),
date_create('1997-12-31 01:00'),
date_create('1997-12-31 02:00'),
date_create('1997-12-31 03:00'))),
array(array('count'=>4,'bymonth'=>'4, 7','byyearday'=>'1, 100, 200, 365'), array(
date_create('1998-04-10 00:00'),
date_create('1998-04-10 01:00'),
date_create('1998-04-10 02:00'),
date_create('1998-04-10 03:00'))),
array(array('count'=>4,'bymonth'=>'4, 7','byyearday'=>'-365, -266, -166, -1'), array(
date_create('1998-04-10 00:00'),
date_create('1998-04-10 01:00'),
date_create('1998-04-10 02:00'),
date_create('1998-04-10 03:00'))),
array(array('byhour'=>'6, 18'), array(
date_create('1997-09-02 18:00'),
date_create('1997-09-03 06:00'),
date_create('1997-09-03 18:00'))),
array(array('byminute'=>'6, 18'),array(
date_create('1997-09-02 09:06'),
date_create('1997-09-02 09:18'),
date_create('1997-09-02 10:06'))),
array(array('bysecond'=>'6, 18'),array(
date_create('1997-09-02 09:00:06'),
date_create('1997-09-02 09:00:18'),
date_create('1997-09-02 10:00:06'))),
array(array('byhour'=>'6, 18','byminute'=>'6, 18'),array(
date_create('1997-09-02 18:06'),
date_create('1997-09-02 18:18'),
date_create('1997-09-03 06:06'))),
array(array('byhour'=>'6, 18','bysecond'=>'6, 18'),array(
date_create('1997-09-02 18:00:06'),
date_create('1997-09-02 18:00:18'),
date_create('1997-09-03 06:00:06'))),
array(array('byminute'=>'6, 18','bysecond'=>'6, 18'),array(
date_create('1997-09-02 09:06:06'),
date_create('1997-09-02 09:06:18'),
date_create('1997-09-02 09:18:06'))),
array(array('byhour'=>'6, 18','byminute'=>'6, 18','bysecond'=>'6, 18'), array(
date_create('1997-09-02 18:06:06'),
date_create('1997-09-02 18:06:18'),
date_create('1997-09-02 18:18:06'))),
// FIXME infinite loop
// array(array('byminute'=>'15, 45','bysecond'=>'15, 45','bysetpos'=>'3, -3'), array(
// date_create('1997-09-02 09:15:45'),
// date_create('1997-09-02 09:45:15'),
// date_create('1997-09-02 10:15:45')))
);
}
/**
* @dataProvider hourlyRules
*/
public function testHourly($rule, $occurrences)
{
$rule = new RRule(array_merge(array(
'FREQ' => 'HOURLY',
'COUNT' => 3,
'DTSTART' => '1997-09-02 09:00:00'
), $rule));
$this->assertEquals($occurrences, $rule->getOccurrences());
foreach ( $occurrences as $date ) {
$this->assertTrue($rule->occursAt($date), $date->format('r'));
}
}
// def testDailyByHour(self):
// self.assertEqual(list(rrule(DAILY,
public function minutelyRules()
{
return array(
array(array(), array(
date_create('1997-09-02 09:00'),
date_create('1997-09-02 09:01'),
date_create('1997-09-02 09:02'))),
array(array('interval'=>2), array(
date_create('1997-09-02 09:00'),
date_create('1997-09-02 09:02'),
date_create('1997-09-02 09:04'))),
array(array('interval'=>1501),array(
date_create('1997-09-02 09:00'),
date_create('1997-09-03 10:01'),
date_create('1997-09-04 11:02'))),
array(array('bymonth'=>'1, 3'),array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 00:01:00'),
date_create('1998-01-01 00:02:00'))),
array(array('bymonthday'=>'1, 3'), array(
date_create('1997-09-03 00:00:00'),
date_create('1997-09-03 00:01:00'),
date_create('1997-09-03 00:02:00'))),
array(array('bymonth'=>'1, 3','bymonthday'=>'5, 7'), array(
date_create('1998-01-05 00:00:00'),
date_create('1998-01-05 00:01:00'),
date_create('1998-01-05 00:02:00'))),
array(array('byday'=>'TU, TH'), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 09:01:00'),
date_create('1997-09-02 09:02:00'))),
array(array('bymonth'=>'1, 3','byday'=>'TU, TH'), array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 00:01:00'),
date_create('1998-01-01 00:02:00'))),
array(array('bymonthday'=>'1, 3','byday'=>'TU, TH'),array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 00:01:00'),
date_create('1998-01-01 00:02:00'))),
array(array('bymonth'=>'1, 3','bymonthday'=>'1, 3','byday'=> 'TU, TH'), array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 00:01:00'),
date_create('1998-01-01 00:02:00'))),
array(array('count'=>4, 'byyearday'=> '1, 100, 200, 365'), array(
date_create('1997-12-31 00:00:00'),
date_create('1997-12-31 00:01:00'),
date_create('1997-12-31 00:02:00'),
date_create('1997-12-31 00:03:00'))),
array(array('count'=>4,'byyearday'=>'-365, -266, -166, -1'), array(
date_create('1997-12-31 00:00:00'),
date_create('1997-12-31 00:01:00'),
date_create('1997-12-31 00:02:00'),
date_create('1997-12-31 00:03:00'))),
array(array('count'=>4,'bymonth'=>'4, 7','byyearday'=>'1, 100, 200, 365'),array(
date_create('1998-04-10 00:00:00'),
date_create('1998-04-10 00:01:00'),
date_create('1998-04-10 00:02:00'),
date_create('1998-04-10 00:03:00'))),
array(array('count'=>4,'bymonth'=>'4, 7','byyearday'=>'-365, -266, -166, -1'),array(
date_create('1998-04-10 00:00:00'),
date_create('1998-04-10 00:01:00'),
date_create('1998-04-10 00:02:00'),
date_create('1998-04-10 00:03:00'))),
array(array('byhour'=>'6, 18'),array(
date_create('1997-09-02 18:00:00'),
date_create('1997-09-02 18:01:00'),
date_create('1997-09-02 18:02:00'))),
array(array('byminute'=>'6, 18'),array(
date_create('1997-09-02 09:06:00'),
date_create('1997-09-02 09:18:00'),
date_create('1997-09-02 10:06:00'))),
array(array('bysecond'=> '6, 18'), array(
date_create('1997-09-02 09:00:06'),
date_create('1997-09-02 09:00:18'),
date_create('1997-09-02 09:01:06'))),
array(array('byhour'=>'6, 18','byminute'=>'6, 18'), array(
date_create('1997-09-02 18:06:00'),
date_create('1997-09-02 18:18:00'),
date_create('1997-09-03 06:06:00'))),
array(array('byhour'=>'6, 18','bysecond'=>'6, 18'), array(
date_create('1997-09-02 18:00:06'),
date_create('1997-09-02 18:00:18'),
date_create('1997-09-02 18:01:06'))),
array(array('byminute'=>'6, 18','bysecond'=>'6, 18'),array(
date_create('1997-09-02 09:06:06'),
date_create('1997-09-02 09:06:18'),
date_create('1997-09-02 09:18:06'))),
array(array('byhour'=>'6, 18','byminute'=>'6, 18','bysecond'=>'6, 18'),array(
date_create('1997-09-02 18:06:06'),
date_create('1997-09-02 18:06:18'),
date_create('1997-09-02 18:18:06'))),
//FIXME
// array(array('bysecond'=>'15, 30, 45','bysetpos'=>'3, -3'),array(
// date_create('1997-09-02 09:00:15'),
// date_create('1997-09-02 09:00:45'),
// date_create('1997-09-02 09:01:15')))
);
}
/**
* @dataProvider minutelyRules
*/
public function testMinutely($rule, $occurrences)
{
$rule = new RRule(array_merge(array(
'FREQ' => 'minutely',
'COUNT' => 3,
'DTSTART' => '1997-09-02 09:00:00'
), $rule));
$this->assertEquals($occurrences, $rule->getOccurrences());
foreach ( $occurrences as $date ) {
$this->assertTrue($rule->occursAt($date), $date->format('r'));
}
}
// byhour=(6, 18),
/**
* SECONDLY rules, mostly taken from the Python test suite
*/
public function secondlyRules()
{
return array(
array(array(), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 09:00:01'),
date_create('1997-09-02 09:00:02'))),
array(array('interval'=>2), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 09:00:02'),
date_create('1997-09-02 09:00:04'))),
array(array('interval'=>90061), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-09-03 10:01:01'),
date_create('1997-09-04 11:02:02'))),
array(array('bymonth'=>'1, 3'),array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 00:00:01'),
date_create('1998-01-01 00:00:02'))),
array(array('bymonthday'=>'1, 3'), array(
date_create('1997-09-03 00:00:00'),
date_create('1997-09-03 00:00:01'),
date_create('1997-09-03 00:00:02'))),
array(array('bymonth'=>'1, 3','bymonthday'=>'5, 7'),array(
date_create('1998-01-05 00:00:00'),
date_create('1998-01-05 00:00:01'),
date_create('1998-01-05 00:00:02'))),
array(array('byday'=>'TU, TH'), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 09:00:01'),
date_create('1997-09-02 09:00:02'))),
array(array('bymonth'=>'1, 3','byday'=>'TU, TH'),array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 00:00:01'),
date_create('1998-01-01 00:00:02'))),
array(array('bymonthday'=>'1, 3','byday'=>'TU, TH'),array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 00:00:01'),
date_create('1998-01-01 00:00:02'))),
array(array('bymonth'=>'1, 3','bymonthday'=>'1, 3','byday'=>'TU, TH'),array(
date_create('1998-01-01 00:00:00'),
date_create('1998-01-01 00:00:01'),
date_create('1998-01-01 00:00:02'))),
array(array('count'=>4,'byyearday'=>'1, 100, 200, 365'),array(
date_create('1997-12-31 00:00:00'),
date_create('1997-12-31 00:00:01'),
date_create('1997-12-31 00:00:02'),
date_create('1997-12-31 00:00:03'))),
array(array('count'=>4,'byyearday'=>'-365, -266, -166, -1'),array(
date_create('1997-12-31 00:00:00'),
date_create('1997-12-31 00:00:01'),
date_create('1997-12-31 00:00:02'),
date_create('1997-12-31 00:00:03'))),
array(array('count'=>4,'bymonth'=>'4, 7','byyearday'=>'1, 100, 200, 365'),array(
date_create('1998-04-10 00:00:00'),
date_create('1998-04-10 00:00:01'),
date_create('1998-04-10 00:00:02'),
date_create('1998-04-10 00:00:03'))),
array(array('count'=>4,'bymonth'=>'4, 7','byyearday'=>'-365, -266, -166, -1'),array(
date_create('1998-04-10 00:00:00'),
date_create('1998-04-10 00:00:01'),
date_create('1998-04-10 00:00:02'),
date_create('1998-04-10 00:00:03'))),
array(array('byhour'=>'6, 18'),array(
date_create('1997-09-02 18:00:00'),
date_create('1997-09-02 18:00:01'),
date_create('1997-09-02 18:00:02'))),
array(array('byminute'=>'6, 18'), array(
date_create('1997-09-02 09:06:00'),
date_create('1997-09-02 09:06:01'),
date_create('1997-09-02 09:06:02'))),
array(array('bysecond'=>'6, 18'), array(
date_create('1997-09-02 09:00:06'),
date_create('1997-09-02 09:00:18'),
date_create('1997-09-02 09:01:06'))),
array(array('byhour'=>'6, 18','byminute'=>'6, 18'), array(
date_create('1997-09-02 18:06:00'),
date_create('1997-09-02 18:06:01'),
date_create('1997-09-02 18:06:02'))),
array(array('byhour'=>'6, 18','bysecond'=>'6, 18'), array(
date_create('1997-09-02 18:00:06'),
date_create('1997-09-02 18:00:18'),
date_create('1997-09-02 18:01:06'))),
array(array('byminute'=>'6, 18','bysecond'=>'6, 18'), array(
date_create('1997-09-02 09:06:06'),
date_create('1997-09-02 09:06:18'),
date_create('1997-09-02 09:18:06'))),
array(array('byhour'=>'6, 18','byminute'=>'6, 18','bysecond'=>'6, 18'), array(
date_create('1997-09-02 18:06:06'),
date_create('1997-09-02 18:06:18'),
date_create('1997-09-02 18:18:06'))),
// TODO BY SETPOS
array(array('bysecond'=>'0','byminute'=>'1','dtstart'=>date_create('2010-03-22 12:01:00')), array(
date_create('2010-03-22 12:01:00'),
date_create('2010-03-22 13:01:00'),
date_create('2010-03-22 14:01:00'))),
// array(date_create('1997-09-02'),
// date_create('1997-09-03'),
// date_create('1997-09-03')))
// def testDailyByMinute(self):
// self.assertEqual(list(rrule(DAILY,
// byminute=(6, 18),
// array(date_create('1997-09-02'),
// date_create('1997-09-02'),
// date_create('1997-09-03')))
// def testDailyBySecond(self):
// self.assertEqual(list(rrule(DAILY,
// bysecond=(6, 18),
// array(date_create('1997-09-02'),
// date_create('1997-09-02'),
// date_create('1997-09-03')))
// def testDailyByHourAndMinute(self):
// self.assertEqual(list(rrule(DAILY,
// byhour=(6, 18),
// byminute=(6, 18),
// array(date_create('1997-09-02'),
// date_create('1997-09-02'),
// date_create('1997-09-03')))
// def testDailyByHourAndSecond(self):
// self.assertEqual(list(rrule(DAILY,
// byhour=(6, 18),
// bysecond=(6, 18),
// array(date_create('1997-09-02'),
// date_create('1997-09-02'),
// date_create('1997-09-03')))
// def testDailyByMinuteAndSecond(self):
// self.assertEqual(list(rrule(DAILY,
// byminute=(6, 18),
// bysecond=(6, 18),
// array(date_create('1997-09-02'),
// date_create('1997-09-02'),
// date_create('1997-09-02')))
// def testDailyByHourAndMinuteAndSecond(self):
// self.assertEqual(list(rrule(DAILY,
// byhour=(6, 18),
// byminute=(6, 18),
// bysecond=(6, 18),
// array(date_create('1997-09-02'),
// date_create('1997-09-02'),
// date_create('1997-09-02')))
// def testDailyBySetPos(self):
// self.assertEqual(list(rrule(DAILY,
// byhour=(6, 18),
// byminute=(15, 45),
// bysetpos=(3, -3),
// array(date_create('1997-09-02'),
// date_create('1997-09-03'),
// date_create('1997-09-03')))
);
}
/**
* @dataProvider secondlyRules
*/
public function testSecondly($rule, $occurrences)
{
$rule = new RRule(array_merge(array(
'FREQ' => 'secondly',
'COUNT' => 3,
'DTSTART' => '1997-09-02 09:00:00'
), $rule));
$this->assertEquals($occurrences, $rule->getOccurrences());
foreach ( $occurrences as $date ) {
$this->assertTrue($rule->occursAt($date), $date->format('r'));
}
}
/**
* Examples given in the RFC.
@ -659,8 +1041,7 @@ class RRuleTest extends PHPUnit_Framework_TestCase
date_create('1999-03-10 09:00:00'),
date_create('1999-03-11 09:00:00'),
date_create('1999-03-12 09:00:00'),
date_create('1999-03-13 09:00:00'))
),
date_create('1999-03-13 09:00:00'))),
// Every Tuesday, every other month, 6 occurences.
array(
array('freq' => 'monthly', 'count' => 6, 'interval' => 2, 'byday' => 'TU', 'dtstart' => '1997-09-02 09:00:00'),
@ -669,8 +1050,7 @@ class RRuleTest extends PHPUnit_Framework_TestCase
date_create('1997-09-16 09:00:00'),
date_create('1997-09-23 09:00:00'),
date_create('1997-09-30 09:00:00'),
date_create('1997-11-04 09:00:00'))
),
date_create('1997-11-04 09:00:00'))),
// Yearly in June and July for 10 occurrences.
array(
array('freq' => 'yearly', 'count' => 10, 'bymonth' => '6,7', 'dtstart' => '1997-06-10 09:00:00'),
@ -790,7 +1170,101 @@ class RRuleTest extends PHPUnit_Framework_TestCase
date_create('1997-10-30 09:00:00'),
date_create('1997-11-27 09:00:00'))
),
// todo HOURLY, MINUTELY, SECONDLY
// Every 3 hours from 9:00 AM to 5:00 PM on a specific day.
array(
array('freq' => 'hourly', 'interval' => 3, 'dtstart' => '1997-09-29 09:00:00', 'until' => '1997-09-29 17:00:00'),
array(date_create('1997-09-29 09:00:00'),
date_create('1997-09-29 12:00:00'),
date_create('1997-09-29 15:00:00'))
),
// Every 15 minutes for 6 occurrences.
array(
array('freq' => 'MINUTELY', 'interval' => 15, 'count' => 6, 'dtstart' => '1997-09-02 09:00:00'),
array(date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 09:15:00'),
date_create('1997-09-02 09:30:00'),
date_create('1997-09-02 09:45:00'),
date_create('1997-09-02 10:00:00'),
date_create('1997-09-02 10:15:00'))
),
// Every hour and a half for 4 occurrences.
array(
array('freq' => 'MINUTELY', 'interval' => 90, 'count' => 4, 'dtstart' => '1997-09-02 09:00:00'),
array(date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 10:30:00'),
date_create('1997-09-02 12:00:00'),
date_create('1997-09-02 13:30:00'))
),
// Every 20 minutes from 9:00 AM to 4:40 PM for two days.
array(
array('freq' => 'MINUTELY', 'interval' => 20, 'count' => 48,
'byhour' => range(9,16), 'byminute' => '0,20,40',
'dtstart' => '1997-09-02 09:00:00'), array(
date_create('1997-09-02 09:00:00'),
date_create('1997-09-02 09:20:00'),
date_create('1997-09-02 09:40:00'),
date_create('1997-09-02 10:00:00'),
date_create('1997-09-02 10:20:00'),
date_create('1997-09-02 10:40:00'),
date_create('1997-09-02 11:00:00'),
date_create('1997-09-02 11:20:00'),
date_create('1997-09-02 11:40:00'),
date_create('1997-09-02 12:00:00'),
date_create('1997-09-02 12:20:00'),
date_create('1997-09-02 12:40:00'),
date_create('1997-09-02 13:00:00'),
date_create('1997-09-02 13:20:00'),
date_create('1997-09-02 13:40:00'),
date_create('1997-09-02 14:00:00'),
date_create('1997-09-02 14:20:00'),
date_create('1997-09-02 14:40:00'),
date_create('1997-09-02 15:00:00'),
date_create('1997-09-02 15:20:00'),
date_create('1997-09-02 15:40:00'),
date_create('1997-09-02 16:00:00'),
date_create('1997-09-02 16:20:00'),
date_create('1997-09-02 16:40:00'),
date_create('1997-09-03 09:00:00'),
date_create('1997-09-03 09:20:00'),
date_create('1997-09-03 09:40:00'),
date_create('1997-09-03 10:00:00'),
date_create('1997-09-03 10:20:00'),
date_create('1997-09-03 10:40:00'),
date_create('1997-09-03 11:00:00'),
date_create('1997-09-03 11:20:00'),
date_create('1997-09-03 11:40:00'),
date_create('1997-09-03 12:00:00'),
date_create('1997-09-03 12:20:00'),
date_create('1997-09-03 12:40:00'),
date_create('1997-09-03 13:00:00'),
date_create('1997-09-03 13:20:00'),
date_create('1997-09-03 13:40:00'),
date_create('1997-09-03 14:00:00'),
date_create('1997-09-03 14:20:00'),
date_create('1997-09-03 14:40:00'),
date_create('1997-09-03 15:00:00'),
date_create('1997-09-03 15:20:00'),
date_create('1997-09-03 15:40:00'),
date_create('1997-09-03 16:00:00'),
date_create('1997-09-03 16:20:00'),
date_create('1997-09-03 16:40:00'))
),
// An example where the days generated makes a difference because of wkst.
array(array('freq' => 'WEEKLY', 'interval' => 2, 'count' => 4,
'byday' => 'TU,SU', 'WKST' => 'MO', 'dtstart' => '1997-08-05 09:00:00'),array(
date_create('1997-08-05 09:00:00'),
date_create('1997-08-10 09:00:00'),
date_create('1997-08-19 09:00:00'),
date_create('1997-08-24 09:00:00'))
),
array(array('freq' => 'WEEKLY', 'interval' => 2, 'count' => 4,
'byday' => 'TU,SU', 'WKST' => 'SU', 'dtstart' => '1997-08-05 09:00:00'),array(
date_create('1997-08-05 09:00:00'),
date_create('1997-08-17 09:00:00'),
date_create('1997-08-19 09:00:00'),
date_create('1997-08-31 09:00:00'))
),
);
}
@ -806,6 +1280,41 @@ class RRuleTest extends PHPUnit_Framework_TestCase
}
}
/**
* Rules that generate no occurence, because of a bad combination of BYXXX parts
* An infinite loop is likely to occur if a test fails.
*/
public function rulesWithoutOccurrences()
{
return array(
// Every year on February and on the week number 50 (impossible)
array(array(
'freq' => 'yearly',
'interval' => 1,
'bymonth' => 2,
'byweekno' => 50,
'dtstart' => '1997-02-02 09:00:00',
'count' => 1
)),
// Every 2 months, on odd months, starting a even month (impossible)
array(array(
'freq' => 'monthly',
'interval' => 2,
'bymonth' => [1,3,5,7,9,11],
'dtstart' => '1997-02-02 09:00:00',
'count' => 1
)),
);
}
/**
* @dataProvider rulesWithoutOccurrences
*/
public function testRulesWithoutOccurrences($rule)
{
$rule = new RRule($rule);
$this->assertEmpty($rule->getOccurrences());
}
/**
* Just some more random rules found here and there. Some of them
* might not bring any additional value to the tests to be honest, but
@ -892,17 +1401,36 @@ class RRuleTest extends PHPUnit_Framework_TestCase
array('FREQ' => 'MONTHLY', 'DTSTART' => '1999-09-02', 'INTERVAL' => 2),
array('1999-10-02', '1999-12-02')
),
// todo weekly,daily
array(
array('freq' => 'hourly', 'dtstart' => '1999-09-02 09:00:00', 'INTERVAL' => 2),
array('1999-09-02 10:00:00', '1999-09-02 12:00:00')
),
array(
array('freq' => 'hourly', 'dtstart' => '1999-09-02 09:00:00', 'INTERVAL' => 5),
array('1999-09-03 09:00:00')
),
);
}
/**
* @dataProvider notOccurrences
*/
public function testDoesNotOccursAt($rule, $not_occurences)
public function testNotOccurrences($rule, $not_occurences)
{
$rule = new RRule($rule);
foreach ( $not_occurences as $date ) {
$this->assertFalse($rule->occursAt($date), $date);
}
}
public function testIsLeapYear()
{
$this->assertFalse(\RRule\is_leap_year(1700));
$this->assertFalse(\RRule\is_leap_year(1800));
$this->assertFalse(\RRule\is_leap_year(1900));
$this->assertTrue(\RRule\is_leap_year(2000));
}
}