2015-06-23 10:31:18 +02:00
< ? php
2018-05-15 18:41:41 +02:00
namespace RRule\Tests ;
2015-06-23 10:31:18 +02:00
2018-05-15 18:41:41 +02:00
use RRule\RRule ;
use DateTime ;
use DateTimeZone ;
use ReflectionClass ;
use stdClass ;
use PHPUnit\Framework\TestCase ;
2016-03-24 08:22:32 +01:00
2018-05-15 18:41:41 +02:00
class RRuleTest extends TestCase
2015-06-23 10:31:18 +02:00
{
2015-06-29 10:45:39 +02:00
/**
* These rules are invalid according to the RFC
*/
2015-06-26 16:02:29 +02:00
public function invalidRules ()
2015-06-23 10:31:18 +02:00
{
return array (
2015-06-27 13:12:57 +02:00
array ( array ()),
2016-06-30 10:51:47 +02:00
array ( array ( 'FOOBAR' => 'DAILY' )),
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'foobar' )),
2019-10-05 02:21:40 +02:00
'Invalid integer frequency' => [[ 'FREQ' => 42 ]],
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'INTERVAL' => - 1 )),
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'INTERVAL' => 1.5 )),
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'UNTIL' => 'foobar' )),
array ( array ( 'FREQ' => 'DAILY' , 'COUNT' => - 1 )),
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'COUNT' => 1.5 )),
2015-07-07 18:16:46 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'UNTIL' => '2015-07-01' , 'COUNT' => 1 )),
2015-06-23 10:31:18 +02:00
2015-07-08 11:40:45 +02:00
array ( array ( 'FREQ' => 'YEARLY' , 'BYDAY' => '1MO,X' )),
2015-06-26 16:02:29 +02:00
// The BYDAY rule part MUST NOT be specified with a numeric value
// when the FREQ rule part is not set to MONTHLY or YEARLY.
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYDAY' => array ( '1MO' ))),
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYDAY' => array ( '1.5MO' ))),
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'WEEKLY' , 'BYDAY' => array ( '1MO' ))),
2015-06-26 16:02:29 +02:00
// The BYDAY rule part MUST NOT be specified with a numeric value
// with the FREQ rule part set to YEARLY when the BYWEEKNO rule part is specified.
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'YEARLY' , 'BYDAY' => array ( '1MO' ), 'BYWEEKNO' => 20 )),
2015-06-23 10:31:18 +02:00
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYMONTHDAY' => 0 )),
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYMONTHDAY' => 1.5 )),
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYMONTHDAY' => 32 )),
array ( array ( 'FREQ' => 'DAILY' , 'BYMONTHDAY' => - 32 )),
2015-07-08 11:40:45 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYMONTHDAY' => '1,A' )),
2015-06-26 16:02:29 +02:00
// The BYMONTHDAY rule part MUST NOT be specified when the FREQ rule
// part is set to WEEKLY.
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'WEEKLY' , 'BYMONTHDAY' => 1 )),
2015-06-23 10:31:18 +02:00
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'YEARLY' , 'BYYEARDAY' => 0 )),
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'YEARLY' , 'BYYEARDAY' => 1.5 )),
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'YEARLY' , 'BYYEARDAY' => 367 )),
2015-07-08 11:40:45 +02:00
array ( array ( 'FREQ' => 'YEARLY' , 'BYYEARDAY' => '1,A' )),
2015-06-26 16:02:29 +02:00
// The BYYEARDAY rule part MUST NOT be specified when the FREQ
// rule part is set to DAILY, WEEKLY, or MONTHLY.
2015-06-27 13:12:57 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYYEARDAY' => 1 )),
array ( array ( 'FREQ' => 'WEEKLY' , 'BYYEARDAY' => 1 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYYEARDAY' => 1 )),
2015-06-23 10:31:18 +02:00
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'MONTHLY' , 'BYMONTH' => 0 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYMONTH' => - 1 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYMONTH' => 1.5 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYMONTH' => 13 )),
2015-06-26 16:02:29 +02:00
// BYSETPOS rule part MUST only be used in conjunction with another
// BYxxx rule part.
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYSETPOS' => 1 )),
array ( array ( 'FREQ' => 'DAILY' , 'BYDAY' => 'MO' , 'BYSETPOS' => 1.5 )),
2015-07-08 11:40:45 +02:00
array ( array ( 'FREQ' => 'DAILY' , 'BYDAY' => 'MO' , 'BYSETPOS' => '1,A' )),
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'YEARLY' , 'BYWEEKNO' => 0 )),
array ( array ( 'FREQ' => 'YEARLY' , 'BYWEEKNO' => 1.5 )),
2019-10-05 02:21:40 +02:00
// The BYWEEKNO rule part MUST NOT be used when the FREQ rule part is set to anything other than YEARLY.
'BYWEEKNO with FREQ not yearly' => [[ 'FREQ' => 'DAILY' , 'BYWEEKNO' => 1 ]],
2017-05-09 18:01:08 +02:00
array ( array ( 'FREQ' => 'MONTHLY' , 'BYHOUR' => - 1 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYHOUR' => 1.5 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYHOUR' => 25 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYMINUTE' => - 1 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYMINUTE' => 1.5 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYMINUTE' => 60 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYSECOND' => - 1 )),
array ( array ( 'FREQ' => 'MONTHLY' , 'BYSECOND' => 1.5 )),
2019-10-05 02:21:40 +02:00
array ( array ( 'FREQ' => 'MONTHLY' , 'BYSECOND' => 61 )),
'Invalid WKST' => [[ 'FREQ' => 'DAILY' , 'WKST' => 'XX' ]],
'Invalid DTSTART (invalid date)' => [[ 'FREQ' => 'DAILY' , 'DTSTART' => new stdClass ()]]
2015-06-23 10:31:18 +02:00
);
}
/**
2015-06-26 16:02:29 +02:00
* @ dataProvider invalidRules
2015-06-23 10:31:18 +02:00
*/
2015-06-26 16:02:29 +02:00
public function testInvalidRules ( $rule )
2015-06-23 10:31:18 +02:00
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2015-06-26 16:02:29 +02:00
new RRule ( $rule );
2015-06-23 10:31:18 +02:00
}
2016-11-11 19:20:09 +01:00
/**
* These rules are valid according to the RFC , just making sure that the lib doesn ' t reject them .
*/
public function validRules ()
{
return array (
// The BYMONTHDAY rule part MUST NOT be specified when the FREQ rule part is set to WEEKLY.
array ( array ( 'FREQ' => 'WEEKLY' , 'BYMONTHDAY' => array ()))
);
}
/**
* @ dataProvider validRules
*/
public function testValidRules ( $rule )
{
2018-05-15 18:41:41 +02:00
$result = new RRule ( $rule );
$this -> assertInstanceOf ( 'RRule\RRule' , $result );
2016-11-11 19:20:09 +01:00
}
2015-06-29 10:45:39 +02:00
/**
* YEARLY rules , mostly taken from Python test suite .
*/
2015-06-23 10:31:18 +02:00
public function yearlyRules ()
{
return array (
2015-06-29 10:45:39 +02:00
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' ))),
2015-06-23 10:31:18 +02:00
// This is interesting because the TH(-3) ends up before the TU(3).
2015-06-29 10:45:39 +02:00
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' ))),
2019-09-01 20:50:21 +02:00
'byyearday positive' => array ( array ( 'BYYEARDAY' => array ( 1 , 100 , 200 , 365 ), 'COUNT' => 4 ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-12-31' ), date_create ( '1998-01-01' ), date_create ( '1998-04-10' ), date_create ( '1998-07-19' ))),
2019-09-01 20:50:21 +02:00
'byyearday negative' => array ( array ( 'BYYEARDAY' => array ( - 365 , - 266 , - 166 , - 1 ), 'COUNT' => 4 ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-12-31' ), date_create ( '1998-01-01' ), date_create ( '1998-04-10' ), date_create ( '1998-07-19' ))),
2019-09-01 20:50:21 +02:00
'byyearday positive + bymonth' => array ( array ( 'BYYEARDAY' => array ( 1 , 100 , 200 , 365 ), 'BYMONTH' => array ( 4 , 7 ), 'COUNT' => 4 ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-04-10' ), date_create ( '1998-07-19' ), date_create ( '1999-04-10' ), date_create ( '1999-07-19' ))),
2019-09-01 20:50:21 +02:00
'byyearday negative + bymonth' => array ( array ( 'BYYEARDAY' => array ( - 365 , - 266 , - 166 , - 1 ), 'BYMONTH' => array ( 4 , 7 ), 'COUNT' => 4 ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-04-10' ), date_create ( '1998-07-19' ), date_create ( '1999-04-10' ), date_create ( '1999-07-19' ))),
2019-09-01 20:50:21 +02:00
'byyearday, 29 February' => [
[ 'BYYEARDAY' => '60' ],
[ date_create ( '1998-03-01' ), date_create ( '1999-03-01' ), date_create ( '2000-02-29' )]
],
'byyearday, 366th day' => [
[ 'BYYEARDAY' => '366' ],
[ date_create ( '2000-12-31' ), date_create ( '2004-12-31' ), date_create ( '2008-12-31' )]
],
'byyearday, -366th day' => [
[ 'BYYEARDAY' => '-366' ],
[ date_create ( '2000-01-01' ), date_create ( '2004-01-01' ), date_create ( '2008-01-01' )]
],
2015-06-29 10:45:39 +02:00
array ( array ( 'BYWEEKNO' => 20 ), array (
date_create ( '1998-05-11' ), date_create ( '1998-05-12' ), date_create ( '1998-05-13' ))),
2015-06-26 16:02:29 +02:00
// That's a nice one. The first days of week number one may be in the last year.
2015-06-29 10:45:39 +02:00
array ( array ( 'BYWEEKNO' => 1 , 'BYDAY' => 'MO' ), array (
date_create ( '1997-12-29' ), date_create ( '1999-01-04' ), date_create ( '2000-01-03' ))),
2015-06-26 16:02:29 +02:00
// Another nice test. The last days of week number 52/53 may be in the next year.
2015-06-29 10:45:39 +02:00
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' ))),
2015-06-30 17:19:09 +02:00
// todo bysetpos
2015-06-29 10:45:39 +02:00
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
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' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYMINUTE' => array ( 15 , 30 )), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:15:00' ),
date_create ( '1997-09-02 06:30:00' ),
date_create ( '1997-09-02 18:15:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYSECOND' => array ( 10 , 20 )), array (
2015-06-29 10:45:39 +02:00
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' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYMINUTE' => array ( 15 , 30 ), 'BYSECOND' => array ( 10 , 20 )), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:15:10' ),
date_create ( '1997-09-02 06:15:20' ),
date_create ( '1997-09-02 06:30:10' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTHDAY' => 15 , 'BYHOUR' => '6,18' , 'BYSETPOS' => array ( 3 , - 3 )), array (
2015-06-30 17:19:09 +02:00
date_create ( '1997-11-15 18:00:00' ),
date_create ( '1998-02-15 06:00:00' ),
date_create ( '1998-11-15 18:00:00' )))
2015-06-23 10:31:18 +02:00
);
}
/**
* @ dataProvider yearlyRules
*/
public function testYearly ( $rule , $occurrences )
{
2015-06-27 13:12:57 +02:00
$rule = new RRule ( array_merge ( array (
2015-06-23 10:31:18 +02:00
'FREQ' => 'YEARLY' ,
'COUNT' => 3 ,
'DTSTART' => '1997-09-02'
2015-06-27 13:12:57 +02:00
), $rule ));
2015-06-23 10:31:18 +02:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences ());
2015-07-02 16:12:48 +02:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2015-07-02 16:12:48 +02:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . 'in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2015-07-02 16:12:48 +02:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . 'in uncached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2015-07-02 16:12:48 +02:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
2015-06-26 20:24:52 +02:00
}
2015-06-23 10:31:18 +02:00
}
2015-06-29 10:45:39 +02:00
/**
* MONTHY rules , mostly taken from the Python test suite
*/
2015-06-23 10:31:18 +02:00
public function monthlyRules ()
{
return array (
2015-06-29 10:45:39 +02:00
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' ))),
2019-10-05 02:21:40 +02:00
'1.5 years' => array ( array ( 'INTERVAL' => 18 ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02' ), date_create ( '1999-03-02' ), date_create ( '2000-09-02' ))),
2019-10-05 02:21:40 +02:00
'exactly 2 years in December' => [
[ 'INTERVAL' => 24 , 'DTSTART' => '1997-12-01' ],
[ date_create ( '1997-12-01' ), date_create ( '1999-12-01' ), date_create ( '2001-12-01' )]
],
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTH' => '1,3' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-02' ), date_create ( '1998-03-02' ), date_create ( '1999-01-02' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTHDAY' => '1,3' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-03' ), date_create ( '1997-10-01' ), date_create ( '1997-10-03' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTHDAY' => array ( 5 , 7 ), 'BYMONTH' => '1,3' ), array (
2015-06-29 10:45:39 +02:00
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' ))),
2015-06-26 16:02:29 +02:00
// Third Monday of the month
2015-06-29 10:45:39 +02:00
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' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYDAY' => 'TU,TH' , 'BYMONTH' => '1,3' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-01' ), date_create ( '1998-01-06' ), date_create ( '1998-01-08' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTH' => '1,3' , 'BYDAY' => '1TU, -1TH' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-06' ), date_create ( '1998-01-29' ), date_create ( '1998-03-03' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTH' => '1,3' , 'BYDAY' => '3TU, -3TH' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-15' ), date_create ( '1998-01-20' ), date_create ( '1998-03-12' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTHDAY' => '1,3' , 'BYDAY' => array ( 'TU' , 'TH' )), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-01' ), date_create ( '1998-02-03' ), date_create ( '1998-03-03' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTH' => '1,3' , 'BYMONTHDAY' => '1,3' , 'BYDAY' => array ( 'TU' , 'TH' )), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-01' ), date_create ( '1998-03-03' ), date_create ( '2001-03-01' ))),
2015-06-30 17:19:09 +02:00
// last workday of the month
array ( array ( 'BYDAY' => 'MO,TU,WE,TH,FR' , 'BYSETPOS' =>- 1 ), array (
date_create ( '1997-09-30' ),
date_create ( '1997-10-31' ),
date_create ( '1997-11-28' ))),
2015-06-29 10:45:39 +02:00
2016-07-13 10:08:46 +02:00
// first working day of the month, or previous Friday
// see http://stackoverflow.com/questions/38170676/recurring-calendar-event-on-first-of-the-month/38314515
array ( array ( 'BYDAY' => '1MO,1TU,1WE,1TH,1FR,-1FR' , 'BYMONTHDAY' => '1,-1,-2' ),
array ( date_create ( '1997-10-01' ), date_create ( '1997-10-31' ), date_create ( '1997-12-01' ))),
array ( array ( 'BYDAY' => '1MO,1TU,1WE,1TH,FR' , 'BYMONTHDAY' => '1,-1,-2' ),
array ( date_create ( '1997-10-01' ), date_create ( '1997-10-31' ), date_create ( '1997-12-01' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:00:00' ), date_create ( '1997-09-02 18:00:00' ), date_create ( '1997-10-02 06:00:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMINUTE' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 00:06:00' ), date_create ( '1997-09-02 00:18:00' ), date_create ( '1997-10-02 00:06:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYSECOND' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 00:00:06' ), date_create ( '1997-09-02 00:00:18' ), date_create ( '1997-10-02 00:00:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYMINUTE' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:06:00' ), date_create ( '1997-09-02 06:18:00' ), date_create ( '1997-09-02 18:06:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYSECOND' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:00:06' ), date_create ( '1997-09-02 06:00:18' ), date_create ( '1997-09-02 18:00:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMINUTE' => '6,18' , 'BYSECOND' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 00:06:06' ), date_create ( '1997-09-02 00:06:18' ), date_create ( '1997-09-02 00:18:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYMINUTE' => '6,18' , 'BYSECOND' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:06:06' ), date_create ( '1997-09-02 06:06:18' ), date_create ( '1997-09-02 06:18:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTHDAY' => array ( 13 , 17 ), 'BYHOUR' => '6,18' , 'BYSETPOS' => array ( 3 , - 3 )), array (
2015-06-30 17:19:09 +02:00
date_create ( '1997-09-13 18:00' ), date_create ( '1997-09-17 06:00' ), date_create ( '1997-10-13 18:00' ))),
// avoid duplicates
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTHDAY' => array ( 13 , 17 ), 'BYHOUR' => '6,18' , 'BYSETPOS' => array ( 3 , 3 , - 3 )), array (
2015-06-30 17:19:09 +02:00
date_create ( '1997-09-13 18:00' ), date_create ( '1997-09-17 06:00' ), date_create ( '1997-10-13 18:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMONTHDAY' => array ( 13 , 17 ), 'BYHOUR' => '6,18' , 'BYSETPOS' => array ( 4 , - 1 )), array (
2015-06-30 17:19:09 +02:00
date_create ( '1997-09-17 18:00' ), date_create ( '1997-10-17 18:00' ), date_create ( '1997-11-17 18:00' )))
2015-06-23 10:31:18 +02:00
);
}
/**
* @ dataProvider monthlyRules
*/
public function testMonthly ( $rule , $occurrences )
{
2015-06-27 13:12:57 +02:00
$rule = new RRule ( array_merge ( array (
2015-06-23 10:31:18 +02:00
'FREQ' => 'MONTHLY' ,
'COUNT' => 3 ,
'DTSTART' => '1997-09-02'
2015-06-27 13:12:57 +02:00
), $rule ));
2015-06-23 10:31:18 +02:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences ());
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in uncached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
2015-06-26 20:24:52 +02:00
}
2015-06-23 10:31:18 +02:00
}
2015-06-26 16:02:29 +02:00
2015-06-29 10:45:39 +02:00
/**
* WEEKLY rules , mostly taken from the Python test suite
*/
2015-06-26 16:02:29 +02:00
public function weeklyRules ()
{
return array (
2015-06-29 10:45:39 +02:00
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' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'bymonth' => '1,3' ), array (
2015-06-29 10:45:39 +02:00
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' ))),
2015-06-26 16:02:29 +02:00
# This test is interesting, because it crosses the year
# boundary in a weekly period to find day '1' as a
# valid recurrence.
2015-07-01 11:23:39 +02:00
array ( array ( 'bymonth' => '1,3' , 'byday' => array ( 'TU' , 'TH' )), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-01' ), date_create ( '1998-01-06' ), date_create ( '1998-01-08' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'byhour' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:00:00' ), date_create ( '1997-09-02 18:00:00' ), date_create ( '1997-09-09 06:00:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'byminute' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 00:06:00' ), date_create ( '1997-09-02 00:18:00' ), date_create ( '1997-09-09 00:06:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'bysecond' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 00:00:06' ), date_create ( '1997-09-02 00:00:18' ), date_create ( '1997-09-09 00:00:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'byhour' => '6,18' , 'byminute' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:06:00' ), date_create ( '1997-09-02 06:18:00' ), date_create ( '1997-09-02 18:06:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'byhour' => '6,18' , 'bysecond' => '6,18' , 'dtstart' => '1997-09-02 09:00:00' ), array (
date_create ( '1997-09-02 18:00:06' ),
date_create ( '1997-09-02 18:00:18' ),
date_create ( '1997-09-09 06:00:06' ))),
array ( array ( 'byminute' => '6,18' , 'bysecond' => '6,18' , 'dtstart' => '1997-09-02 09:00:00' ), 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' , 'dtstart' => '1997-09-02 09:00:00' ), 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' ))),
array ( array ( 'byday' => array ( 'TU' , 'TH' ), 'byhour' => '6,18' , 'bysetpos' => array ( 3 , - 3 ), 'dtstart' => '1997-09-02 09:00:00' ), array (
date_create ( '1997-09-02 18:00:00' ),
date_create ( '1997-09-04 06:00:00' ),
date_create ( '1997-09-09 18:00:00' )))
2015-06-26 16:02:29 +02:00
);
}
2016-03-21 21:43:38 +01:00
2015-06-26 16:02:29 +02:00
/**
* @ dataProvider weeklyRules
*/
public function testWeekly ( $rule , $occurrences )
{
2015-06-27 13:12:57 +02:00
$rule = new RRule ( array_merge ( array (
2015-06-26 16:02:29 +02:00
'FREQ' => 'WEEKLY' ,
'COUNT' => 3 ,
'DTSTART' => '1997-09-02'
2015-06-27 13:12:57 +02:00
), $rule ));
2015-06-26 16:02:29 +02:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences ());
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in uncached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
2015-06-26 20:24:52 +02:00
}
2015-06-26 16:02:29 +02:00
}
2015-06-29 10:45:39 +02:00
/**
* DAILY rules , mostly taken from the Python test suite
*/
2015-06-26 16:02:29 +02:00
public function dailyRules ()
{
return array (
2015-06-29 10:45:39 +02:00
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' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'bymonth' => '1,3' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-01' ), date_create ( '1998-01-02' ), date_create ( '1998-01-03' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'bymonthday' => '1,3' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-03' ), date_create ( '1997-10-01' ), date_create ( '1997-10-03' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'bymonth' => '1,3' , 'bymonthday' => array ( 5 , 7 )), array (
2015-06-29 10:45:39 +02:00
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' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'bymonth' => '1,3' , 'byday' => array ( 'TU' , 'TH' )), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-01' ), date_create ( '1998-01-06' ), date_create ( '1998-01-08' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'bymonthday' => '1,3' , 'byday' => array ( 'TU' , 'TH' )), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-01' ), date_create ( '1998-02-03' ), date_create ( '1998-03-03' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'bymonth' => '1,3' , 'bymonthday' => '1,3' , 'byday' => array ( 'TU' , 'TH' )), array (
2015-06-29 10:45:39 +02:00
date_create ( '1998-01-01' ), date_create ( '1998-03-03' ), date_create ( '2001-03-01' ))),
// TODO BYSETPOS
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:00:00' ), date_create ( '1997-09-02 18:00:00' ), date_create ( '1997-09-03 06:00:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMINUTE' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 00:06:00' ), date_create ( '1997-09-02 00:18:00' ), date_create ( '1997-09-03 00:06:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYSECOND' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 00:00:06' ), date_create ( '1997-09-02 00:00:18' ), date_create ( '1997-09-03 00:00:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYMINUTE' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:06:00' ), date_create ( '1997-09-02 06:18:00' ), date_create ( '1997-09-02 18:06:00' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYSECOND' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:00:06' ), date_create ( '1997-09-02 06:00:18' ), date_create ( '1997-09-02 18:00:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYMINUTE' => '6,18' , 'BYSECOND' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 00:06:06' ), date_create ( '1997-09-02 00:06:18' ), date_create ( '1997-09-02 00:18:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'BYMINUTE' => '6,18' , 'BYSECOND' => '6,18' ), array (
2015-06-29 10:45:39 +02:00
date_create ( '1997-09-02 06:06:06' ), date_create ( '1997-09-02 06:06:18' ), date_create ( '1997-09-02 06:18:06' ))),
2015-07-01 11:23:39 +02:00
array ( array ( 'BYHOUR' => '6,18' , 'byminute' => '15,45' , 'BYSETPOS' => array ( 3 , - 3 ), 'dtstart' => '1997-09-02, 09:00' ), array (
date_create ( '1997-09-02 18:15' ),
date_create ( '1997-09-03 06:45' ),
date_create ( '1997-09-03 18:15' )))
2015-06-29 10:45:39 +02:00
2015-06-26 16:02:29 +02:00
);
}
2016-03-21 21:43:38 +01:00
2015-06-26 16:02:29 +02:00
/**
* @ dataProvider dailyRules
*/
public function testDaily ( $rule , $occurrences )
{
2015-06-27 13:12:57 +02:00
$rule = new RRule ( array_merge ( array (
2015-06-26 16:02:29 +02:00
'FREQ' => 'DAILY' ,
'COUNT' => 3 ,
'DTSTART' => '1997-09-02'
2015-06-27 13:12:57 +02:00
), $rule ));
2015-06-26 16:02:29 +02:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences ());
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in uncached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
2015-06-26 20:24:52 +02:00
}
2015-06-26 16:02:29 +02:00
}
2015-06-29 10:45:39 +02:00
/**
* 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' ))),
2019-09-01 20:50:21 +02:00
'byyearday, 29 February' => [
[ 'BYYEARDAY' => '60' ],
[ date_create ( '1998-03-01 00:00' ), date_create ( '1998-03-01 01:00' ), date_create ( '1998-03-01 02:00' )]
],
'byyearday, 366th day' => [
[ 'BYYEARDAY' => '366' ],
[ date_create ( '2000-12-31 00:00' ), date_create ( '2000-12-31 01:00' ), date_create ( '2000-12-31 02:00' )]
],
'byyearday, -366th day' => [
[ 'BYYEARDAY' => '-366' ],
[ date_create ( '2000-01-01 00:00' ), date_create ( '2000-01-01 01:00' ), date_create ( '2000-01-01 02:00' )]
],
2015-06-29 10:45:39 +02: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' ))),
2015-07-01 11:23:39 +02:00
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' )))
2015-06-29 10:45:39 +02:00
);
}
/**
* @ 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 ());
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in uncached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
2015-06-29 10:45:39 +02:00
}
}
2015-06-26 16:02:29 +02:00
2015-07-01 11:23:39 +02:00
/**
* MINUTELY rules , mostly taken from the Python test suite
*/
2015-06-29 10:45:39 +02:00
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' ))),
2015-07-01 11:23:39 +02:00
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' )))
2015-06-29 10:45:39 +02:00
);
}
/**
* @ 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 ());
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in uncached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
2015-06-29 10:45:39 +02:00
}
}
2015-06-26 16:02:29 +02:00
2015-06-29 10:45:39 +02:00
/**
* 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' ))),
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' ))),
);
}
/**
* @ 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 ());
2015-07-02 16:12:48 +02:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2015-07-02 16:12:48 +02:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2015-07-02 16:12:48 +02:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in uncached version' );
2015-06-29 10:45:39 +02:00
}
2016-03-24 08:22:32 +01:00
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
}
2015-06-29 10:45:39 +02:00
}
2015-06-26 20:24:52 +02:00
2015-06-27 12:50:28 +02:00
/**
* Examples given in the RFC .
*/
public function rfcExamples ()
{
return array (
// Daily, for 10 occurrences.
array (
2016-03-11 06:42:34 +01:00
array ( 'freq' => 'daily' , 'count' => 10 , 'dtstart' => date_create ( '1997-09-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))),
array ( date_create ( '1997-09-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-04 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-05 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-06 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-07 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-08 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-09 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-10 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-11 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )))
),
array (
array ( 'freq' => 'daily' , 'count' => 10 , 'dtstart' => date_create ( '2016-10-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))),
array ( date_create ( '2016-10-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-03 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-04 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-05 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-06 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-07 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-08 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-09 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-10 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-10-11 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )))
),
array (
array ( 'freq' => 'daily' , 'count' => 10 , 'dtstart' => date_create ( '2016-04-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))),
array ( date_create ( '2016-04-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-03 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-04 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-05 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-06 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-07 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-08 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-09 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-10 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '2016-04-11 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )))
2015-06-27 12:50:28 +02:00
),
// Daily until December 24, 1997
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'daily' , 'dtstart' => '1997-09-02 09:00:00' , 'until' => '1997-12-24 00:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ), date_create ( '1997-09-03 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-04 09:00:00' ), date_create ( '1997-09-05 09:00:00' ),
date_create ( '1997-09-06 09:00:00' ), date_create ( '1997-09-07 09:00:00' ),
date_create ( '1997-09-08 09:00:00' ), date_create ( '1997-09-09 09:00:00' ),
date_create ( '1997-09-10 09:00:00' ), date_create ( '1997-09-11 09:00:00' ),
date_create ( '1997-09-12 09:00:00' ), date_create ( '1997-09-13 09:00:00' ),
date_create ( '1997-09-14 09:00:00' ), date_create ( '1997-09-15 09:00:00' ),
date_create ( '1997-09-16 09:00:00' ), date_create ( '1997-09-17 09:00:00' ),
date_create ( '1997-09-18 09:00:00' ), date_create ( '1997-09-19 09:00:00' ),
date_create ( '1997-09-20 09:00:00' ), date_create ( '1997-09-21 09:00:00' ),
date_create ( '1997-09-22 09:00:00' ), date_create ( '1997-09-23 09:00:00' ),
date_create ( '1997-09-24 09:00:00' ), date_create ( '1997-09-25 09:00:00' ),
date_create ( '1997-09-26 09:00:00' ), date_create ( '1997-09-27 09:00:00' ),
date_create ( '1997-09-28 09:00:00' ), date_create ( '1997-09-29 09:00:00' ),
date_create ( '1997-09-30 09:00:00' ), date_create ( '1997-10-01 09:00:00' ),
date_create ( '1997-10-02 09:00:00' ), date_create ( '1997-10-03 09:00:00' ),
date_create ( '1997-10-04 09:00:00' ), date_create ( '1997-10-05 09:00:00' ),
date_create ( '1997-10-06 09:00:00' ), date_create ( '1997-10-07 09:00:00' ),
date_create ( '1997-10-08 09:00:00' ), date_create ( '1997-10-09 09:00:00' ),
date_create ( '1997-10-10 09:00:00' ), date_create ( '1997-10-11 09:00:00' ),
date_create ( '1997-10-12 09:00:00' ), date_create ( '1997-10-13 09:00:00' ),
date_create ( '1997-10-14 09:00:00' ), date_create ( '1997-10-15 09:00:00' ),
date_create ( '1997-10-16 09:00:00' ), date_create ( '1997-10-17 09:00:00' ),
date_create ( '1997-10-18 09:00:00' ), date_create ( '1997-10-19 09:00:00' ),
date_create ( '1997-10-20 09:00:00' ), date_create ( '1997-10-21 09:00:00' ),
date_create ( '1997-10-22 09:00:00' ), date_create ( '1997-10-23 09:00:00' ),
date_create ( '1997-10-24 09:00:00' ), date_create ( '1997-10-25 09:00:00' ),
date_create ( '1997-10-26 09:00:00' ), date_create ( '1997-10-27 09:00:00' ),
date_create ( '1997-10-28 09:00:00' ), date_create ( '1997-10-29 09:00:00' ),
date_create ( '1997-10-30 09:00:00' ), date_create ( '1997-10-31 09:00:00' ),
date_create ( '1997-11-01 09:00:00' ),
date_create ( '1997-11-02 09:00:00' ), date_create ( '1997-11-03 09:00:00' ),
date_create ( '1997-11-04 09:00:00' ), date_create ( '1997-11-05 09:00:00' ),
date_create ( '1997-11-06 09:00:00' ), date_create ( '1997-11-07 09:00:00' ),
date_create ( '1997-11-08 09:00:00' ), date_create ( '1997-11-09 09:00:00' ),
date_create ( '1997-11-10 09:00:00' ), date_create ( '1997-11-11 09:00:00' ),
date_create ( '1997-11-12 09:00:00' ), date_create ( '1997-11-13 09:00:00' ),
date_create ( '1997-11-14 09:00:00' ), date_create ( '1997-11-15 09:00:00' ),
date_create ( '1997-11-16 09:00:00' ), date_create ( '1997-11-17 09:00:00' ),
date_create ( '1997-11-18 09:00:00' ), date_create ( '1997-11-19 09:00:00' ),
date_create ( '1997-11-20 09:00:00' ), date_create ( '1997-11-21 09:00:00' ),
date_create ( '1997-11-22 09:00:00' ), date_create ( '1997-11-23 09:00:00' ),
date_create ( '1997-11-24 09:00:00' ), date_create ( '1997-11-25 09:00:00' ),
date_create ( '1997-11-26 09:00:00' ), date_create ( '1997-11-27 09:00:00' ),
date_create ( '1997-11-28 09:00:00' ), date_create ( '1997-11-29 09:00:00' ),
date_create ( '1997-11-30 09:00:00' ), date_create ( '1997-12-01 09:00:00' ),
date_create ( '1997-12-02 09:00:00' ), date_create ( '1997-12-03 09:00:00' ),
date_create ( '1997-12-04 09:00:00' ), date_create ( '1997-12-05 09:00:00' ),
date_create ( '1997-12-06 09:00:00' ), date_create ( '1997-12-07 09:00:00' ),
date_create ( '1997-12-08 09:00:00' ), date_create ( '1997-12-09 09:00:00' ),
date_create ( '1997-12-10 09:00:00' ), date_create ( '1997-12-11 09:00:00' ),
date_create ( '1997-12-12 09:00:00' ), date_create ( '1997-12-13 09:00:00' ),
date_create ( '1997-12-14 09:00:00' ), date_create ( '1997-12-15 09:00:00' ),
date_create ( '1997-12-16 09:00:00' ), date_create ( '1997-12-17 09:00:00' ),
date_create ( '1997-12-18 09:00:00' ), date_create ( '1997-12-19 09:00:00' ),
date_create ( '1997-12-20 09:00:00' ), date_create ( '1997-12-21 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-12-22 09:00:00' ), date_create ( '1997-12-23 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every other day, 5 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'daily' , 'interval' => 2 , 'count' => 5 , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-04 09:00:00' ),
date_create ( '1997-09-06 09:00:00' ),
date_create ( '1997-09-08 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-09-10 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every 10 days, 5 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'daily' , 'interval' => 10 , 'count' => 5 , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-12 09:00:00' ),
date_create ( '1997-09-22 09:00:00' ),
date_create ( '1997-10-02 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-10-12 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Everyday in January, for 3 years.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'bymonth' => 1 , 'byday' => 'MO,TU,WE,TH,FR,SA,SU' , 'dtstart' => '1997-09-02 09:00:00' , 'until' => '2000-01-31 09:00:00' ),
array ( date_create ( '1998-01-01 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1998-01-02 09:00:00' ), date_create ( '1998-01-03 09:00:00' ),
date_create ( '1998-01-04 09:00:00' ), date_create ( '1998-01-05 09:00:00' ),
date_create ( '1998-01-06 09:00:00' ), date_create ( '1998-01-07 09:00:00' ),
date_create ( '1998-01-08 09:00:00' ), date_create ( '1998-01-09 09:00:00' ),
date_create ( '1998-01-10 09:00:00' ), date_create ( '1998-01-11 09:00:00' ),
date_create ( '1998-01-12 09:00:00' ), date_create ( '1998-01-13 09:00:00' ),
date_create ( '1998-01-14 09:00:00' ), date_create ( '1998-01-15 09:00:00' ),
date_create ( '1998-01-16 09:00:00' ), date_create ( '1998-01-17 09:00:00' ),
date_create ( '1998-01-18 09:00:00' ), date_create ( '1998-01-19 09:00:00' ),
date_create ( '1998-01-20 09:00:00' ), date_create ( '1998-01-21 09:00:00' ),
date_create ( '1998-01-22 09:00:00' ), date_create ( '1998-01-23 09:00:00' ),
date_create ( '1998-01-24 09:00:00' ), date_create ( '1998-01-25 09:00:00' ),
date_create ( '1998-01-26 09:00:00' ), date_create ( '1998-01-27 09:00:00' ),
date_create ( '1998-01-28 09:00:00' ), date_create ( '1998-01-29 09:00:00' ),
date_create ( '1998-01-30 09:00:00' ), date_create ( '1998-01-31 09:00:00' ),
date_create ( '1999-01-01 09:00:00' ),
date_create ( '1999-01-02 09:00:00' ), date_create ( '1999-01-03 09:00:00' ),
date_create ( '1999-01-04 09:00:00' ), date_create ( '1999-01-05 09:00:00' ),
date_create ( '1999-01-06 09:00:00' ), date_create ( '1999-01-07 09:00:00' ),
date_create ( '1999-01-08 09:00:00' ), date_create ( '1999-01-09 09:00:00' ),
date_create ( '1999-01-10 09:00:00' ), date_create ( '1999-01-11 09:00:00' ),
date_create ( '1999-01-12 09:00:00' ), date_create ( '1999-01-13 09:00:00' ),
date_create ( '1999-01-14 09:00:00' ), date_create ( '1999-01-15 09:00:00' ),
date_create ( '1999-01-16 09:00:00' ), date_create ( '1999-01-17 09:00:00' ),
date_create ( '1999-01-18 09:00:00' ), date_create ( '1999-01-19 09:00:00' ),
date_create ( '1999-01-20 09:00:00' ), date_create ( '1999-01-21 09:00:00' ),
date_create ( '1999-01-22 09:00:00' ), date_create ( '1999-01-23 09:00:00' ),
date_create ( '1999-01-24 09:00:00' ), date_create ( '1999-01-25 09:00:00' ),
date_create ( '1999-01-26 09:00:00' ), date_create ( '1999-01-27 09:00:00' ),
date_create ( '1999-01-28 09:00:00' ), date_create ( '1999-01-29 09:00:00' ),
date_create ( '1999-01-30 09:00:00' ), date_create ( '1999-01-31 09:00:00' ),
date_create ( '2000-01-01 09:00:00' ),
date_create ( '2000-01-02 09:00:00' ), date_create ( '2000-01-03 09:00:00' ),
date_create ( '2000-01-04 09:00:00' ), date_create ( '2000-01-05 09:00:00' ),
date_create ( '2000-01-06 09:00:00' ), date_create ( '2000-01-07 09:00:00' ),
date_create ( '2000-01-08 09:00:00' ), date_create ( '2000-01-09 09:00:00' ),
date_create ( '2000-01-10 09:00:00' ), date_create ( '2000-01-11 09:00:00' ),
date_create ( '2000-01-12 09:00:00' ), date_create ( '2000-01-13 09:00:00' ),
date_create ( '2000-01-14 09:00:00' ), date_create ( '2000-01-15 09:00:00' ),
date_create ( '2000-01-16 09:00:00' ), date_create ( '2000-01-17 09:00:00' ),
date_create ( '2000-01-18 09:00:00' ), date_create ( '2000-01-19 09:00:00' ),
date_create ( '2000-01-20 09:00:00' ), date_create ( '2000-01-21 09:00:00' ),
date_create ( '2000-01-22 09:00:00' ), date_create ( '2000-01-23 09:00:00' ),
date_create ( '2000-01-24 09:00:00' ), date_create ( '2000-01-25 09:00:00' ),
date_create ( '2000-01-26 09:00:00' ), date_create ( '2000-01-27 09:00:00' ),
date_create ( '2000-01-28 09:00:00' ), date_create ( '2000-01-29 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '2000-01-30 09:00:00' ), date_create ( '2000-01-31 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Same thing, in another way
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'daily' , 'bymonth' => 1 , 'dtstart' => '1997-09-02 09:00:00' , 'until' => '2000-01-31 09:00:00' ),
array ( date_create ( '1998-01-01 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1998-01-02 09:00:00' ), date_create ( '1998-01-03 09:00:00' ),
date_create ( '1998-01-04 09:00:00' ), date_create ( '1998-01-05 09:00:00' ),
date_create ( '1998-01-06 09:00:00' ), date_create ( '1998-01-07 09:00:00' ),
date_create ( '1998-01-08 09:00:00' ), date_create ( '1998-01-09 09:00:00' ),
date_create ( '1998-01-10 09:00:00' ), date_create ( '1998-01-11 09:00:00' ),
date_create ( '1998-01-12 09:00:00' ), date_create ( '1998-01-13 09:00:00' ),
date_create ( '1998-01-14 09:00:00' ), date_create ( '1998-01-15 09:00:00' ),
date_create ( '1998-01-16 09:00:00' ), date_create ( '1998-01-17 09:00:00' ),
date_create ( '1998-01-18 09:00:00' ), date_create ( '1998-01-19 09:00:00' ),
date_create ( '1998-01-20 09:00:00' ), date_create ( '1998-01-21 09:00:00' ),
date_create ( '1998-01-22 09:00:00' ), date_create ( '1998-01-23 09:00:00' ),
date_create ( '1998-01-24 09:00:00' ), date_create ( '1998-01-25 09:00:00' ),
date_create ( '1998-01-26 09:00:00' ), date_create ( '1998-01-27 09:00:00' ),
date_create ( '1998-01-28 09:00:00' ), date_create ( '1998-01-29 09:00:00' ),
date_create ( '1998-01-30 09:00:00' ), date_create ( '1998-01-31 09:00:00' ),
date_create ( '1999-01-01 09:00:00' ),
date_create ( '1999-01-02 09:00:00' ), date_create ( '1999-01-03 09:00:00' ),
date_create ( '1999-01-04 09:00:00' ), date_create ( '1999-01-05 09:00:00' ),
date_create ( '1999-01-06 09:00:00' ), date_create ( '1999-01-07 09:00:00' ),
date_create ( '1999-01-08 09:00:00' ), date_create ( '1999-01-09 09:00:00' ),
date_create ( '1999-01-10 09:00:00' ), date_create ( '1999-01-11 09:00:00' ),
date_create ( '1999-01-12 09:00:00' ), date_create ( '1999-01-13 09:00:00' ),
date_create ( '1999-01-14 09:00:00' ), date_create ( '1999-01-15 09:00:00' ),
date_create ( '1999-01-16 09:00:00' ), date_create ( '1999-01-17 09:00:00' ),
date_create ( '1999-01-18 09:00:00' ), date_create ( '1999-01-19 09:00:00' ),
date_create ( '1999-01-20 09:00:00' ), date_create ( '1999-01-21 09:00:00' ),
date_create ( '1999-01-22 09:00:00' ), date_create ( '1999-01-23 09:00:00' ),
date_create ( '1999-01-24 09:00:00' ), date_create ( '1999-01-25 09:00:00' ),
date_create ( '1999-01-26 09:00:00' ), date_create ( '1999-01-27 09:00:00' ),
date_create ( '1999-01-28 09:00:00' ), date_create ( '1999-01-29 09:00:00' ),
date_create ( '1999-01-30 09:00:00' ), date_create ( '1999-01-31 09:00:00' ),
date_create ( '2000-01-01 09:00:00' ),
date_create ( '2000-01-02 09:00:00' ), date_create ( '2000-01-03 09:00:00' ),
date_create ( '2000-01-04 09:00:00' ), date_create ( '2000-01-05 09:00:00' ),
date_create ( '2000-01-06 09:00:00' ), date_create ( '2000-01-07 09:00:00' ),
date_create ( '2000-01-08 09:00:00' ), date_create ( '2000-01-09 09:00:00' ),
date_create ( '2000-01-10 09:00:00' ), date_create ( '2000-01-11 09:00:00' ),
date_create ( '2000-01-12 09:00:00' ), date_create ( '2000-01-13 09:00:00' ),
date_create ( '2000-01-14 09:00:00' ), date_create ( '2000-01-15 09:00:00' ),
date_create ( '2000-01-16 09:00:00' ), date_create ( '2000-01-17 09:00:00' ),
date_create ( '2000-01-18 09:00:00' ), date_create ( '2000-01-19 09:00:00' ),
date_create ( '2000-01-20 09:00:00' ), date_create ( '2000-01-21 09:00:00' ),
date_create ( '2000-01-22 09:00:00' ), date_create ( '2000-01-23 09:00:00' ),
date_create ( '2000-01-24 09:00:00' ), date_create ( '2000-01-25 09:00:00' ),
date_create ( '2000-01-26 09:00:00' ), date_create ( '2000-01-27 09:00:00' ),
date_create ( '2000-01-28 09:00:00' ), date_create ( '2000-01-29 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '2000-01-30 09:00:00' ), date_create ( '2000-01-31 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Weekly for 10 occurrences:
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'weekly' , 'count' => 10 , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-09 09:00:00' ),
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-10-07 09:00:00' ),
date_create ( '1997-10-14 09:00:00' ),
date_create ( '1997-10-21 09:00:00' ),
date_create ( '1997-10-28 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-11-04 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every other week, 6 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'weekly' , 'interval' => 2 , 'count' => 6 , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-16 09:00:00' ),
date_create ( '1997-09-30 09:00:00' ),
date_create ( '1997-10-14 09:00:00' ),
date_create ( '1997-10-28 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-11-11 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Weekly on Tuesday and Thursday for 5 weeks, week starting on Sunday.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'weekly' , 'count' => 10 , 'wkst' => 'SU' , 'byday' => 'TU,TH' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-04 09:00:00' ),
date_create ( '1997-09-09 09:00:00' ),
date_create ( '1997-09-11 09:00:00' ),
date_create ( '1997-09-16 09:00:00' ),
date_create ( '1997-09-18 09:00:00' ),
date_create ( '1997-09-23 09:00:00' ),
date_create ( '1997-09-25 09:00:00' ),
date_create ( '1997-09-30 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-10-02 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every other week on Tuesday and Thursday, for 8 occurrences, week starting on Sunday
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'weekly' , 'interval' => 2 , 'count' => 8 , 'wkst' => 'SU' , 'byday' => 'TU,TH' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-04 09:00:00' ),
date_create ( '1997-09-16 09:00:00' ),
date_create ( '1997-09-18 09:00:00' ),
date_create ( '1997-09-30 09:00:00' ),
date_create ( '1997-10-02 09:00:00' ),
date_create ( '1997-10-14 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-10-16 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Monthly on the 1st Friday for ten occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'count' => 10 , 'byday' => '1FR' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-05 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-10-03 09:00:00' ),
date_create ( '1997-11-07 09:00:00' ),
date_create ( '1997-12-05 09:00:00' ),
date_create ( '1998-01-02 09:00:00' ),
date_create ( '1998-02-06 09:00:00' ),
date_create ( '1998-03-06 09:00:00' ),
date_create ( '1998-04-03 09:00:00' ),
date_create ( '1998-05-01 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1998-06-05 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every other month on the 1st and last Sunday of the month for 10 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'interval' => 2 , 'count' => 10 , 'byday' => '1SU,-1SU' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-07 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-28 09:00:00' ),
date_create ( '1997-11-02 09:00:00' ),
date_create ( '1997-11-30 09:00:00' ),
date_create ( '1998-01-04 09:00:00' ),
date_create ( '1998-01-25 09:00:00' ),
date_create ( '1998-03-01 09:00:00' ),
date_create ( '1998-03-29 09:00:00' ),
date_create ( '1998-05-03 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1998-05-31 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Monthly on the second to last Monday of the month for 6 months.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'count' => 6 , 'byday' => '-2MO' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-22 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-10-20 09:00:00' ),
date_create ( '1997-11-17 09:00:00' ),
date_create ( '1997-12-22 09:00:00' ),
date_create ( '1998-01-19 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1998-02-16 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Monthly on the third to the last day of the month, for 6 months.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'count' => 6 , 'bymonthday' => '-3' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-28 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-10-29 09:00:00' ),
date_create ( '1997-11-28 09:00:00' ),
date_create ( '1997-12-29 09:00:00' ),
date_create ( '1998-01-29 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1998-02-26 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Monthly on the 2nd and 15th of the month for 5 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'count' => 5 , 'bymonthday' => '2,15' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-15 09:00:00' ),
date_create ( '1997-10-02 09:00:00' ),
date_create ( '1997-10-15 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-11-02 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Monthly on the first and last day of the month for 3 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'count' => 5 , 'bymonthday' => '-1,1' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-30 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-10-01 09:00:00' ),
date_create ( '1997-10-31 09:00:00' ),
date_create ( '1997-11-01 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-11-30 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every 18 months on the 10th thru 15th of the month for 10 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'count' => 10 , 'interval' => 18 , 'bymonthday' => range ( 10 , 15 ), 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-10 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-11 09:00:00' ),
date_create ( '1997-09-12 09:00:00' ),
date_create ( '1997-09-13 09:00:00' ),
date_create ( '1997-09-14 09:00:00' ),
date_create ( '1997-09-15 09:00:00' ),
date_create ( '1999-03-10 09:00:00' ),
date_create ( '1999-03-11 09:00:00' ),
date_create ( '1999-03-12 09:00:00' ),
2015-06-29 10:45:39 +02:00
date_create ( '1999-03-13 09:00:00' ))),
2021-01-09 14:18:28 +01:00
// Every Tuesday, every other month, 6 occurrences.
2015-06-27 12:50:28 +02:00
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'count' => 6 , 'interval' => 2 , 'byday' => 'TU' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-02 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-09-09 09:00:00' ),
date_create ( '1997-09-16 09:00:00' ),
date_create ( '1997-09-23 09:00:00' ),
date_create ( '1997-09-30 09:00:00' ),
2015-06-29 10:45:39 +02:00
date_create ( '1997-11-04 09:00:00' ))),
2015-06-27 12:50:28 +02:00
// Yearly in June and July for 10 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'count' => 10 , 'bymonth' => '6,7' , 'dtstart' => '1997-06-10 09:00:00' ),
array ( date_create ( '1997-06-10 09:00:00' ), date_create ( '1997-07-10 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1998-06-10 09:00:00' ), date_create ( '1998-07-10 09:00:00' ),
date_create ( '1999-06-10 09:00:00' ), date_create ( '1999-07-10 09:00:00' ),
date_create ( '2000-06-10 09:00:00' ), date_create ( '2000-07-10 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '2001-06-10 09:00:00' ), date_create ( '2001-07-10 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every 3rd year on the 1st, 100th and 200th day for 4 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'count' => 4 , 'interval' => '3' , 'byyearday' => '1,100,200' , 'dtstart' => '1997-01-01 09:00:00' ),
array ( date_create ( '1997-01-01 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-04-10 09:00:00' ),
date_create ( '1997-07-19 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '2000-01-01 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every 20th Monday of the year, 3 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'count' => 3 , 'byday' => '20MO' , 'dtstart' => '1997-05-19 09:00:00' ),
array ( date_create ( '1997-05-19 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1998-05-18 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1999-05-17 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Monday of week number 20 (where the default start of the week is Monday), 3 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'count' => 3 , 'byweekno' => 20 , 'byday' => 'MO' , 'dtstart' => '1997-05-12 09:00:00' ),
array ( date_create ( '1997-05-12 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1998-05-11 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1999-05-17 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every Thursday in March
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'byday' => 'TH' , 'bymonth' => 3 , 'dtstart' => '1997-03-13 09:00:00' , 'until' => '2000-01-01' ),
array ( date_create ( '1997-03-13 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-03-20 09:00:00' ),
date_create ( '1997-03-27 09:00:00' ),
date_create ( '1998-03-05 09:00:00' ),
date_create ( '1998-03-12 09:00:00' ),
date_create ( '1998-03-19 09:00:00' ),
date_create ( '1998-03-26 09:00:00' ),
date_create ( '1999-03-04 09:00:00' ),
date_create ( '1999-03-11 09:00:00' ),
date_create ( '1999-03-18 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1999-03-25 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every Thursday, but only during June, July, and August
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'byday' => 'TH' , 'bymonth' => array ( 6 , 7 , 8 ), 'dtstart' => '1997-01-01 09:00:00' , 'until' => '1999-01-01' ),
array ( date_create ( '1997-06-05 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-06-12 09:00:00' ),
date_create ( '1997-06-19 09:00:00' ),
date_create ( '1997-06-26 09:00:00' ),
date_create ( '1997-07-03 09:00:00' ),
date_create ( '1997-07-10 09:00:00' ),
date_create ( '1997-07-17 09:00:00' ),
date_create ( '1997-07-24 09:00:00' ),
date_create ( '1997-07-31 09:00:00' ),
date_create ( '1997-08-07 09:00:00' ),
date_create ( '1997-08-14 09:00:00' ),
date_create ( '1997-08-21 09:00:00' ),
date_create ( '1997-08-28 09:00:00' ),
date_create ( '1998-06-04 09:00:00' ),
date_create ( '1998-06-11 09:00:00' ),
date_create ( '1998-06-18 09:00:00' ),
date_create ( '1998-06-25 09:00:00' ),
date_create ( '1998-07-02 09:00:00' ),
date_create ( '1998-07-09 09:00:00' ),
date_create ( '1998-07-16 09:00:00' ),
date_create ( '1998-07-23 09:00:00' ),
date_create ( '1998-07-30 09:00:00' ),
date_create ( '1998-08-06 09:00:00' ),
date_create ( '1998-08-13 09:00:00' ),
date_create ( '1998-08-20 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1998-08-27 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every Friday the 13th, 4 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'byday' => 'FR' , 'bymonthday' => 13 , 'count' => 4 , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1998-02-13 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1998-03-13 09:00:00' ),
date_create ( '1998-11-13 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1999-08-13 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// The first Saturday that follows the first Sunday of the month
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'byday' => 'SA' , 'bymonthday' => array ( 7 , 8 , 9 , 10 , 11 , 12 , 13 ), 'count' => 10 , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-09-13 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-10-11 09:00:00' ),
date_create ( '1997-11-08 09:00:00' ),
date_create ( '1997-12-13 09:00:00' ),
date_create ( '1998-01-10 09:00:00' ),
date_create ( '1998-02-07 09:00:00' ),
date_create ( '1998-03-07 09:00:00' ),
date_create ( '1998-04-11 09:00:00' ),
date_create ( '1998-05-09 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1998-06-13 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Every four years, the first Tuesday after a Monday in November, 3 occurrences (U.S. Presidential Election day):
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'interval' => 4 , 'bymonth' => 11 , 'byday' => 'TU' , 'bymonthday' => array ( 2 , 3 , 4 , 5 , 6 , 7 , 8 ), 'count' => 3 , 'dtstart' => '1996-11-05 09:00:00' ),
array ( date_create ( '1996-11-05 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '2000-11-07 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '2004-11-02 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// The 3rd instance into the month of one of Tuesday, Wednesday or Thursday, for the next 3 months:
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'byday' => 'TU,WE,TH' , 'bysetpos' => 3 , 'count' => 3 , 'dtstart' => '1997-09-04 09:00:00' ),
array ( date_create ( '1997-09-04 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-10-07 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-11-06 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// The 2nd to last weekday of the month, 3 occurrences.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'monthly' , 'byday' => 'MO,TU,WE,TH,FR' , 'bysetpos' => - 2 , 'count' => 3 , 'dtstart' => '1997-09-29 09:00:00' ),
array ( date_create ( '1997-09-29 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1997-10-30 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '1997-11-27 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
2015-06-29 10:45:39 +02:00
// 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 (
2016-03-11 06:42:34 +01:00
array ( 'freq' => 'MINUTELY' , 'interval' => 90 , 'count' => 4 , 'dtstart' => date_create ( '1997-09-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))),
array ( date_create ( '1997-09-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 10:30:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 12:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 13:30:00' , new DateTimeZone ( 'Australia/Sydney' )))
2015-06-29 10:45:39 +02: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' ,
2016-03-11 06:42:34 +01:00
'dtstart' => date_create ( '1997-09-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))), array (
date_create ( '1997-09-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 09:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 09:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 10:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 10:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 10:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 11:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 11:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 11:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 12:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 12:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 12:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 13:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 13:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 13:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 14:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 14:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 14:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 15:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 15:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 15:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 16:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 16:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-02 16:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 09:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 09:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 10:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 10:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 10:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 11:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 11:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 11:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 12:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 12:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 12:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 13:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 13:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 13:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 14:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 14:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 14:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 15:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 15:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 15:40:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 16:00:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 16:20:00' , new DateTimeZone ( 'Australia/Sydney' )),
date_create ( '1997-09-03 16:40:00' , new DateTimeZone ( 'Australia/Sydney' )))
2015-06-29 10:45:39 +02: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' ))
),
2015-06-27 12:50:28 +02:00
);
}
/**
* @ dataProvider rfcExamples
*/
public function testRfcExamples ( $rule , $occurrences )
{
$rule = new RRule ( $rule );
$this -> assertEquals ( $occurrences , $rule -> getOccurrences ());
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in uncached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
2015-06-27 12:50:28 +02:00
}
}
2015-06-29 10:45:39 +02:00
/**
2021-01-09 14:18:28 +01:00
* Rules that generate no occurrence , because of a bad combination of BYXXX parts
2015-07-01 11:23:39 +02:00
* This tests are here to ensure that the lib will not go into an infinite loop .
2015-06-29 10:45:39 +02:00
*/
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
)),
2015-07-01 11:23:39 +02:00
// Every 2 months, on odd months, starting a even month (nope)
2015-06-29 10:45:39 +02:00
array ( array (
'freq' => 'monthly' ,
'interval' => 2 ,
2015-06-30 17:19:09 +02:00
'bymonth' => '1,3,5,7,9,11' ,
2015-06-29 10:45:39 +02:00
'dtstart' => '1997-02-02 09:00:00' ,
'count' => 1
)),
2015-07-01 13:13:59 +02:00
2021-01-09 14:18:28 +01:00
// haven't found a weekly rule with no occurrence yet
2015-07-01 13:13:59 +02:00
2015-07-01 11:23:39 +02:00
// every 7 days, monday, starting a wednesday (still nope)
array ( array (
'freq' => 'daily' ,
'interval' => 7 ,
'byday' => 'MO' ,
'dtstart' => '2015-07-01 09:00:00' ,
'count' => 1
)),
// every 4 hours, on odd hours, starting an even hour (nein)
array ( array (
'freq' => 'hourly' ,
'interval' => 4 ,
'byhour' => '7, 11, 15, 19' ,
'dtstart' => '1997-09-02 09:00:00' ,
'count' => 1
)),
array ( array (
'freq' => 'minutely' ,
'interval' => 12 ,
'byminute' => '10, 11, 25, 39, 50' ,
'dtstart' => '1997-09-02 09:00:00' ,
'count' => 1
)),
array ( array (
'freq' => 'minutely' ,
'interval' => 120 ,
'byminute' => '10, 12, 14, 16' ,
'dtstart' => '1997-09-02 09:00:00' ,
'count' => 1
)),
array ( array (
'freq' => 'secondly' ,
'interval' => 10 ,
'bysecond' => '2, 15, 37, 42, 59' ,
'dtstart' => '1997-09-02 09:00:00' ,
'count' => 1
)),
array ( array (
'freq' => 'secondly' ,
'interval' => 360 ,
'bysecond' => '10, 28, 49' ,
'dtstart' => '1997-09-02 09:00:00' ,
'count' => 1
)),
array ( array (
'freq' => 'secondly' ,
'interval' => 43200 ,
'bysecond' => '2, 10, 18, 23' ,
'dtstart' => '1997-09-02 09:00:00' ,
'count' => 1
))
2015-06-29 10:45:39 +02:00
);
}
/**
* @ dataProvider rulesWithoutOccurrences
*/
public function testRulesWithoutOccurrences ( $rule )
{
$rule = new RRule ( $rule );
2015-07-01 11:56:09 +02:00
$occurrences = $rule -> getOccurrences ();
$this -> assertEmpty ( $rule -> getOccurrences (), 'This should be empty : ' . json_encode ( $occurrences ));
2015-06-29 10:45:39 +02:00
}
2015-06-27 12:50:28 +02:00
/**
2015-07-01 11:23:39 +02:00
* Just some more random rules found here and there , with some edges cases .
* Some of them might not bring any additional value to the tests to be honest , but
2015-06-27 12:50:28 +02:00
* it ' s good to test them anyway .
*/
public function variousRules ()
{
return array (
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'daily' , 'count' => 3 , 'byday' => 'TU,TH' , 'dtstart' => '2007-01-01' ),
array ( date_create ( '2007-01-02' ), date_create ( '2007-01-04' ), date_create ( '2007-01-09' ))
2015-06-27 12:50:28 +02:00
),
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'weekly' , 'count' => 3 , 'byday' => 'TU,TH' , 'dtstart' => '2007-01-01' ),
array ( date_create ( '2007-01-02' ), date_create ( '2007-01-04' ), date_create ( '2007-01-09' ))
2015-06-27 12:50:28 +02:00
),
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'daily' , 'count' => 3 , 'byday' => 'TU,TH' , 'dtstart' => '2007-01-01' , 'bysetpos' => 1 ),
array ( date_create ( '2007-01-02' ), date_create ( '2007-01-04' ), date_create ( '2007-01-09' ))
2015-06-27 12:50:28 +02:00
),
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'weekly' , 'count' => 3 , 'byday' => 'TU,TH' , 'dtstart' => '2007-01-01' , 'bysetpos' => 1 ),
array ( date_create ( '2007-01-02' ), date_create ( '2007-01-09' ), date_create ( '2007-01-16' ))
2015-06-27 12:50:28 +02:00
),
// The week number 1 may be in the last year.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'count' => 3 , 'byweekno' => 1 , 'byday' => 'MO' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-12-29 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1999-01-04 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '2000-01-03 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// And the week numbers greater than 51 may be in the next year.
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'count' => 3 , 'byweekno' => 52 , 'byday' => 'SU' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1997-12-28 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '1998-12-27 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '2000-01-02 09:00:00' ))
2015-06-27 12:50:28 +02:00
),
// Only some years have week number 53
array (
2015-06-27 13:12:57 +02:00
array ( 'freq' => 'yearly' , 'count' => 3 , 'byweekno' => 53 , 'byday' => 'MO' , 'dtstart' => '1997-09-02 09:00:00' ),
array ( date_create ( '1998-12-28 09:00:00' ),
2015-06-27 12:50:28 +02:00
date_create ( '2004-12-27 09:00:00' ),
2015-06-27 13:12:57 +02:00
date_create ( '2009-12-28 09:00:00' ))
2015-07-01 11:23:39 +02:00
),
// test that occurrences are returned in chronogical order, even when the BYXXX are not in order
array (
array ( 'freq' => 'yearly' , 'bymonth' => '2,1' , 'count' => 3 , 'dtstart' => '2015-07-01 09:00:00' ),
array ( date_create ( '2016-01-01 09:00:00' ),
date_create ( '2016-02-01 09:00:00' ),
date_create ( '2017-01-01 09:00:00' ))
),
array (
array ( 'freq' => 'yearly' , 'byweekno' => '30,50,40' , 'byday' => 'MO' , 'count' => 3 , 'dtstart' => '2015-07-01 09:00:00' ),
array ( date_create ( '2015-07-20 09:00:00' ),
date_create ( '2015-09-28 09:00:00' ),
date_create ( '2015-12-07 09:00:00' ))
),
array (
array ( 'freq' => 'yearly' , 'byyearday' => '3,2,1' , 'count' => 3 , 'dtstart' => '2015-07-01 09:00:00' ),
array ( date_create ( '2016-01-01 09:00:00' ),
date_create ( '2016-01-02 09:00:00' ),
date_create ( '2016-01-03 09:00:00' ))
),
array (
array ( 'freq' => 'yearly' , 'bymonthday' => '31,30' , 'count' => 3 , 'dtstart' => '2015-07-01 09:00:00' ),
array ( date_create ( '2015-07-30 09:00:00' ),
date_create ( '2015-07-31 09:00:00' ),
date_create ( '2015-08-30 09:00:00' ))
),
array (
array ( 'freq' => 'yearly' , 'byday' => 'TU,MO' , 'count' => 3 , 'dtstart' => '2015-07-01 09:00:00' ),
array ( date_create ( '2015-07-06 09:00:00' ),
date_create ( '2015-07-07 09:00:00' ),
date_create ( '2015-07-13 09:00:00' ))
),
array (
array ( 'freq' => 'yearly' , 'byhour' => '9,8' , 'count' => 3 , 'dtstart' => '2015-07-01 09:00:00' ),
array ( date_create ( '2015-07-01 09:00:00' ),
date_create ( '2016-07-01 08:00:00' ),
date_create ( '2016-07-01 09:00:00' ))
),
array (
array ( 'freq' => 'yearly' , 'byminute' => '30,15' , 'count' => 3 , 'dtstart' => '2015-07-01 09:00:00' ),
array ( date_create ( '2015-07-01 09:15:00' ),
date_create ( '2015-07-01 09:30:00' ),
date_create ( '2016-07-01 09:15:00' ))
),
array (
array ( 'freq' => 'yearly' , 'bysecond' => '30,15' , 'count' => 3 , 'dtstart' => '2015-07-01 09:00:00' ),
array ( date_create ( '2015-07-01 09:00:15' ),
date_create ( '2015-07-01 09:00:30' ),
date_create ( '2016-07-01 09:00:15' ))
),
2015-07-01 13:13:59 +02:00
// every 52 weeks, in November, starting in July (will happen in 2185 - to test year 2038 problem)
array ( array (
'freq' => 'weekly' ,
'interval' => 52 ,
'bymonth' => 11 ,
'dtstart' => '2015-07-01 09:00:00' ,
'count' => 1 ), array (
date_create ( '2185-11-30 09:00:00' )
)),
2015-06-27 12:50:28 +02:00
);
}
/**
* @ dataProvider variousRules
*/
public function testVariousRules ( $rule , $occurrences )
{
$rule = new RRule ( $rule );
$this -> assertEquals ( $occurrences , $rule -> getOccurrences ());
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), 'Cached version' );
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in cached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $occurrences as $date ) {
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rule -> occursAt ( $date ), $date -> format ( 'r' ) . ' in uncached version' );
}
$rule -> clearCache ();
2019-01-14 14:09:43 +01:00
for ( $i = 0 ; $i < count ( $occurrences ); $i ++ ) {
2016-03-24 08:22:32 +01:00
$this -> assertEquals ( $rule [ $i ], $occurrences [ $i ], 'array access uncached' );
2015-06-27 12:50:28 +02:00
}
}
/**
2015-07-01 11:23:39 +02:00
* Test that occursAt doesn ' t return false positives
2015-06-27 12:50:28 +02:00
*/
2015-06-26 20:24:52 +02:00
public function notOccurrences ()
{
return array (
array (
2015-06-27 13:12:57 +02:00
array ( 'FREQ' => 'YEARLY' , 'DTSTART' => '1999-09-02' ),
2015-07-01 11:23:39 +02:00
array ( '1999-09-01' , '1999-09-02 12:00:00' , '1999-09-03' )
2015-06-26 20:24:52 +02:00
),
array (
2015-06-27 13:12:57 +02:00
array ( 'FREQ' => 'YEARLY' , 'DTSTART' => '1999-09-02' , 'UNTIL' => '2000-09-02' ),
2015-07-01 11:23:39 +02:00
array ( '2001-09-02' , '2000-09-02 12:00:00' )
2015-06-26 20:24:52 +02:00
),
array (
2015-06-27 13:12:57 +02:00
array ( 'FREQ' => 'YEARLY' , 'DTSTART' => '1999-09-02' , 'COUNT' => 3 ),
array ( '2010-09-02' )
2015-06-26 20:24:52 +02:00
),
array (
2015-06-27 13:12:57 +02:00
array ( 'FREQ' => 'YEARLY' , 'DTSTART' => '1999-09-02' , 'INTERVAL' => 2 ),
array ( '2000-09-02' , '2002-09-02' )
2015-06-26 20:24:52 +02:00
),
2019-10-05 02:21:40 +02:00
'byyearday' => [
[ 'FREQ' => 'YEARLY' , 'DTSTART' => '1999-09-02' , 'byyearday' => 1 ],
[ '1999-09-02' ]
],
'byweekno' => [
[ 'FREQ' => 'YEARLY' , 'DTSTART' => '2015-07-01' , 'BYWEEKNO' => 1 ],
[ '2015-07-01' ]
],
2015-06-26 20:24:52 +02:00
array (
2015-06-27 13:12:57 +02:00
array ( 'FREQ' => 'MONTHLY' , 'DTSTART' => '1999-09-02' , 'INTERVAL' => 2 ),
array ( '1999-10-02' , '1999-12-02' )
2015-06-26 20:24:52 +02:00
),
2019-10-05 02:21:40 +02:00
'bymonth' => [
[ 'FREQ' => 'MONTHLY' , 'DTSTART' => '1999-09-02' , 'bymonth' => 1 ],
[ '1999-10-02' , '1999-12-02' ]
],
2015-07-01 11:23:39 +02:00
array (
array ( 'FREQ' => 'WEEKLY' , 'DTSTART' => '2015-07-01' , 'INTERVAL' => 2 ),
2019-10-05 02:21:40 +02:00
array ( '2015-07-02' , '2015-07-07 23:59:59' , '2015-07-08 00:00:01' , '2015-07-08' )
2015-07-01 11:23:39 +02:00
),
array (
array ( 'FREQ' => 'DAILY' , 'DTSTART' => '2015-07-01' , 'INTERVAL' => 2 ),
array ( '2015-07-02' , '2015-07-02 23:59:59' , '2015-07-03 00:00:01' )
),
2015-06-29 10:45:39 +02:00
array (
array ( 'freq' => 'hourly' , 'dtstart' => '1999-09-02 09:00:00' , 'INTERVAL' => 2 ),
2015-06-30 17:19:09 +02:00
array ( '1999-09-02 10:00:00' , '1999-09-02 09:01:01' , '1999-09-02 12:00:00' )
2015-06-29 10:45:39 +02:00
),
array (
array ( 'freq' => 'hourly' , 'dtstart' => '1999-09-02 09:00:00' , 'INTERVAL' => 5 ),
array ( '1999-09-03 09:00:00' )
),
2015-07-01 11:23:39 +02:00
array (
array ( 'freq' => 'minutely' , 'dtstart' => '1999-09-02 09:00:00' , 'INTERVAL' => 5 ),
array ( '1999-09-02 09:01:00' )
),
array (
array ( 'freq' => 'secondly' , 'dtstart' => '1999-09-02 09:00:00' , 'INTERVAL' => 5 ),
array ( '1999-09-02 09:00:01' )
),
2015-06-26 20:24:52 +02:00
);
}
2019-10-05 02:21:40 +02:00
2015-06-26 20:24:52 +02:00
/**
* @ dataProvider notOccurrences
*/
2021-01-09 14:18:28 +01:00
public function testNotOccurrences ( $rule , $not_occurrences )
2015-06-26 20:24:52 +02:00
{
2015-06-27 13:18:58 +02:00
$rule = new RRule ( $rule );
2021-01-09 14:18:28 +01:00
foreach ( $not_occurrences as $date ) {
2015-07-01 11:56:09 +02:00
$this -> assertFalse ( $rule -> occursAt ( $date ), " Rule must not match $date " );
2015-06-26 20:24:52 +02:00
}
}
2015-06-29 10:45:39 +02:00
2019-11-01 12:48:41 +01:00
public function rulesBeyondMaxCycles ()
{
return [
[ 'yearly' => 'YEARLY' , 30 ],
[ 'monthly' => 'MONTHLY' , 400 ],
[ 'weekly' => 'WEEKLY' , 1500 ],
[ 'daily' => 'DAILY' , 11000 ],
[ 'hourly' => 'HOURLY' , 30 ],
[ 'minutely' => 'MINUTELY' , 1500 ]
];
}
/**
* @ dataProvider rulesBeyondMaxCycles
*/
public function testMaxCyclesDoesntKickInIfTheRuleProduceOccurrences ( $frequency , $count )
{
// see https://github.com/rlanvin/php-rrule/issues/78
$rrule = new RRule ([ 'FREQ' => $frequency , 'COUNT' => $count ]);
$this -> assertEquals ( $count , $rrule -> count ());
}
2023-01-06 11:01:00 +01:00
/**
* Tests timezone transition in Daylight Savings Time switch .
*/
public function testDST ()
{
$rrule = new RRule ([
'FREQ' => 'WEEKLY' ,
'DTSTART' => new \DateTime ( '2022-10-30T01:00' , new \DateTimeZone ( 'America/Chicago' )),
'COUNT' => 2 ,
]);
$this -> assertSame ( '2022-11-06T01:00:00-05:00 CDT 1667714400' , $rrule [ 1 ] -> format ( 'c T U' ));
}
2017-05-06 13:58:42 +02:00
///////////////////////////////////////////////////////////////////////////////
// GetOccurrences
public function testGetOccurrences ()
{
$rrule = new RRule ( array (
'FREQ' => 'DAILY' ,
'DTSTART' => '2017-01-01'
));
$this -> assertCount ( 1 , $rrule -> getOccurrences ( 1 ));
2017-05-06 14:35:15 +02:00
$this -> assertEquals ( array ( date_create ( '2017-01-01' )), $rrule -> getOccurrences ( 1 ));
2017-05-06 13:58:42 +02:00
$this -> assertCount ( 5 , $rrule -> getOccurrences ( 5 ));
2017-05-06 14:35:15 +02:00
$this -> assertEquals ( array (
2017-05-06 13:58:42 +02:00
date_create ( '2017-01-01' ), date_create ( '2017-01-02' ), date_create ( '2017-01-03' ),
date_create ( '2017-01-04' ), date_create ( '2017-01-05' )
2017-05-06 14:35:15 +02:00
), $rrule -> getOccurrences ( 5 ));
2018-05-15 18:41:41 +02:00
}
2017-05-06 13:58:42 +02:00
2018-05-15 18:41:41 +02:00
public function testGetOccurrencesThrowsLogicException ()
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \LogicException :: class );
$this -> expectExceptionMessage ( " Cannot get all occurrences of an infinite recurrence rule. " );
2018-05-15 18:41:41 +02:00
$rrule = new RRule ( array (
'FREQ' => 'DAILY' ,
'DTSTART' => '2017-01-01'
));
$rrule -> getOccurrences ();
2017-05-06 13:58:42 +02:00
}
2019-01-13 14:40:21 +01:00
public function testGetOccurrencesNegativeLimit ()
2017-05-06 13:58:42 +02:00
{
2019-01-13 14:40:21 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2017-05-06 13:58:42 +02:00
$rrule = new RRule ( array (
'FREQ' => 'DAILY' ,
'DTSTART' => '2017-01-01'
));
2019-01-13 14:40:21 +01:00
$rrule -> getOccurrences ( - 1 );
}
2017-05-06 13:58:42 +02:00
2019-01-13 14:40:21 +01:00
public function occurrencesBetween ()
{
return [
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-01' , null , 1 , [ date_create ( '2017-01-01' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-02-01' , '2017-12-31' , 1 , [ date_create ( '2017-02-01' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-01' , null , 5 , [
date_create ( '2017-01-01' ),
date_create ( '2017-01-02' ),
date_create ( '2017-01-03' ),
date_create ( '2017-01-04' ),
date_create ( '2017-01-05' ),
]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-01' , '2017-01-05' , null , [
date_create ( '2017-01-01' ),
date_create ( '2017-01-02' ),
date_create ( '2017-01-03' ),
date_create ( '2017-01-04' ),
date_create ( '2017-01-05' ),
]],
];
}
/**
* @ dataProvider occurrencesBetween
*/
public function testGetOccurrencesBetween ( $rule , $begin , $end , $limit , $expected )
{
$rrule = new RRule ( $rule );
$this -> assertEquals ( $expected , $rrule -> getOccurrencesBetween ( $begin , $end , $limit ));
2018-05-15 18:41:41 +02:00
}
public function testGetOccurrencesBetweenThrowsLogicException ()
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \LogicException :: class );
$this -> expectExceptionMessage ( " Cannot get all occurrences of an infinite recurrence rule. " );
2018-05-15 18:41:41 +02:00
$rrule = new RRule ( array (
'FREQ' => 'DAILY' ,
'DTSTART' => '2017-01-01'
));
$rrule -> getOccurrencesBetween ( '2017-01-01' , null );
2017-05-06 13:58:42 +02:00
}
2019-01-13 14:40:21 +01:00
public function testGetOccurrencesBetweenNegativeLimit ()
{
$this -> expectException ( \InvalidArgumentException :: class );
$rrule = new RRule ( array (
'FREQ' => 'DAILY' ,
'DTSTART' => '2017-01-01'
));
$rrule -> getOccurrencesBetween ( '2017-01-01' , '2018-01-01' , - 1 );
}
public function occurrencesAfter ()
{
return [
2021-01-07 18:18:47 +01:00
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;UNTIL=20170103 " , '2017-01-01' , false , null , [ date_create ( '2017-01-02' ), date_create ( '2017-01-03' )]],
2021-01-09 14:18:28 +01:00
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;UNTIL=20170103 " , '2017-01-01' , true , null , [ date_create ( '2017-01-01' ), date_create ( '2017-01-02' ), date_create ( '2017-01-03' )]],
2019-01-13 14:40:21 +01:00
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-02-01' , false , 2 , [ date_create ( '2017-02-02' ), date_create ( '2017-02-03' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-02-01' , true , 2 , [ date_create ( '2017-02-01' ), date_create ( '2017-02-02' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-02' , true , 2 , [ date_create ( '2017-01-03' ), date_create ( '2017-01-05' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-02' , false , 2 , [ date_create ( '2017-01-03' ), date_create ( '2017-01-05' )]],
];
}
/**
* @ dataProvider occurrencesAfter
*/
public function testGetOccurrencesAfter ( $rrule , $date , $inclusive , $limit , $expected )
{
$rrule = new RRule ( $rrule );
$occurrences = $rrule -> getOccurrencesAfter ( $date , $inclusive , $limit );
$this -> assertEquals ( $expected , $occurrences );
}
2021-01-09 14:18:28 +01:00
public function testGetOccurrencesAfterThrowsLogicException ()
{
$this -> expectException ( \LogicException :: class );
$this -> expectExceptionMessage ( " Cannot get all occurrences of an infinite recurrence rule. " );
$rrule = new RRule ( array (
'FREQ' => 'DAILY' ,
'DTSTART' => '2017-01-01'
));
$rrule -> getOccurrencesAfter ( '2017-01-01' );
}
2019-01-13 14:40:21 +01:00
public function occurrencesBefore ()
{
return [
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-02-01' , true , 2 , [ date_create ( '2017-01-31' ), date_create ( '2017-02-01' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-02-01' , false , 2 , [ date_create ( '2017-01-30' ), date_create ( '2017-01-31' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-02' , false , null , [ date_create ( '2017-01-01' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-02' , false , 5 , [ date_create ( '2017-01-01' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-04' , true , 2 , [ date_create ( '2017-01-01' ), date_create ( '2017-01-03' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-04' , false , 2 , [ date_create ( '2017-01-01' ), date_create ( '2017-01-03' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-02' , false , null , [ date_create ( '2017-01-01' )]],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-02' , false , 5 , [ date_create ( '2017-01-01' )]],
];
}
/**
* @ dataProvider occurrencesBefore
*/
public function testGetOccurrencesBefore ( $rrule , $date , $inclusive , $limit , $expected )
{
$rrule = new RRule ( $rrule );
$occurrences = $rrule -> getOccurrencesBefore ( $date , $inclusive , $limit );
$this -> assertEquals ( $expected , $occurrences );
}
public function nthOccurrences ()
{
return [
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-01' , 0 , date_create ( '2017-01-01' )],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-01' , 1 , date_create ( '2017-01-02' )],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-01' , 2 , date_create ( '2017-01-05' )],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-02' , 0 , null ],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-01' , - 1 , null ],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-10' , - 1 , date_create ( '2017-01-09' )],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY " , '2017-01-10' , - 2 , date_create ( '2017-01-08' )],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-11' , - 2 , date_create ( '2017-01-07' )],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;INTERVAL=2 " , '2017-01-10' , - 2 , date_create ( '2017-01-07' )],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;COUNT=2 " , '2017-01-01' , 3 , null ],
[ " DTSTART:20170101 \n RRULE:FREQ=DAILY;UNTIL=20170102 " , '2017-01-01' , 3 , null ],
];
}
/**
* @ dataProvider nthOccurrences
*/
public function testGetNthOccurrenceFrom ( $rrule , $date , $index , $result )
{
$rrule = new RRule ( $rrule );
$occurrence = $rrule -> getNthOccurrenceFrom ( $date , $index );
$this -> assertEquals ( $result , $occurrence );
}
2019-10-05 02:21:40 +02:00
public function testGetNthOccurrenceFromInvalidIndex ()
{
$rrule = new RRule ([ 'FREQ' => 'DAILY' ]);
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2019-10-05 02:21:40 +02:00
$rrule -> getNthOccurrenceFrom ( date_create ( '2017-01-09' ), []);
}
public function testGetNthOccurrenceBeforeInvalidIndex ()
{
$rrule = new RRule ([ 'FREQ' => 'DAILY' ]);
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2019-10-05 02:21:40 +02:00
$rrule -> getNthOccurrenceBefore ( date_create ( '2017-01-09' ), - 1 );
}
public function testGetNthOccurrenceAfterInvalidIndex ()
{
$rrule = new RRule ([ 'FREQ' => 'DAILY' ]);
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2019-10-05 02:21:40 +02:00
$rrule -> getNthOccurrenceAfter ( date_create ( '2017-01-09' ), - 1 );
}
2019-01-13 14:40:21 +01:00
2016-03-23 11:03:43 +01:00
///////////////////////////////////////////////////////////////////////////////
2016-06-30 10:51:47 +02:00
// RFC Strings
2016-03-23 11:03:43 +01:00
2021-05-07 14:59:35 +02:00
public function rfcStrings ()
2015-07-08 11:40:45 +02:00
{
return array (
2017-02-02 18:30:10 +01:00
// full RFC string
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = HOURLY ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTH = 1 ; BYHOUR = 1 ' ,
null // todo
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = DAILY ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTH = 1 ' ,
null // todo
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = DAILY ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTH = 1 ; BYHOUR = 12 ; BYMINUTE = 15 , 30 ' ,
null
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = WEEKLY ; INTERVAL = 2 ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ' ,
null // todo
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = WEEKLY ; INTERVAL = 2 ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ' ,
null // todo
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = MONTHLY ; INTERVAL = 1 ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTH = 1 ' ,
array ()
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = MONTHLY ; INTERVAL = 1 ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTHDAY = 1 , 2 , 5 , 31 , - 1 , - 3 , - 15 ' ,
array (
date_create ( '1997-09-01 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-09-05 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-10-01 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-10-17 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-10-29 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-10-31 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-11-05 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-11-28 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-12-01 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-12-05 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-12-17 09:00:00' , new DateTimeZone ( 'America/New_York' ))
)
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = MONTHLY ; INTERVAL = 1 ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTHDAY = 1 , 2 , 5 , 31 , - 1 , - 3 , - 15 ; BYSETPOS =- 1 ' ,
array (
date_create ( '1997-09-05 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-10-31 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-11-28 09:00:00' , new DateTimeZone ( 'America/New_York' )),
)
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = MONTHLY ; INTERVAL = 1 ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTHDAY = 1 , 2 , 5 , 31 , - 1 , - 3 , - 15 ; BYSETPOS =- 1 , 1 ' ,
array (
date_create ( '1997-09-01 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-09-05 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-10-01 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-10-31 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-11-05 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-11-28 09:00:00' , new DateTimeZone ( 'America/New_York' )),
date_create ( '1997-12-01 09:00:00' , new DateTimeZone ( 'America/New_York' ))
)
),
2015-07-08 11:40:45 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970512 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = YEARLY ; BYWEEKNO = 20 , 30 , 40 ; BYDAY = MO ' ,
null
),
2016-06-30 10:51:47 +02:00
array ( ' DTSTART ; TZID = America / New_York : 19970512 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = YEARLY ; BYYEARDAY = 1 , - 1 , 10 , - 50 ; BYDAY = MO ' ,
null
),
2016-06-30 10:51:47 +02:00
array ( ' DTSTART : 19970512 T090000Z
2017-02-02 18:30:10 +01:00
RRULE : FREQ = YEARLY ' ,
null
),
2016-06-30 10:51:47 +02:00
array ( ' DTSTART : 19970512 T090000
2017-02-02 18:30:10 +01:00
RRULE : FREQ = YEARLY ' ,
null
),
2016-06-30 10:51:47 +02:00
array ( ' DTSTART : 19970512
2017-02-02 18:30:10 +01:00
RRULE : FREQ = YEARLY ' ,
null
),
// case insensitive
2017-03-29 15:20:00 +02:00
// array("dtstart:19970902T090000\nrrule:freq=yearly;count=3",
// array(date_create('1997-09-02 09:00:00'),date_create('1998-09-02 09:00:00'),date_create('1999-09-02 09:00:00'))
// ),
2017-02-02 18:30:10 +01:00
// empty lines
array ( " \n DTSTART:19970512 \n RRULE:FREQ=YEARLY;COUNT=3 \n \n " ,
array ( date_create ( '1997-05-12' ), date_create ( '1998-05-12' ), date_create ( '1999-05-12' ))
),
2017-05-06 14:35:15 +02:00
// CRLF
array ( " \r \n DTSTART:19970512 \r \n RRULE:FREQ=YEARLY;COUNT=3 \r \n \r \n " ,
array ( date_create ( '1997-05-12' ), date_create ( '1998-05-12' ), date_create ( '1999-05-12' ))
),
2017-02-02 18:30:10 +01:00
// no DTSTART
array ( " RRULE:FREQ=YEARLY;COUNT=3 " ,
null
),
array ( " RRULE:FREQ=YEARLY;UNTIL=20170202 " ,
null
),
array ( " RRULE:FREQ=YEARLY;UNTIL=20170202T090000 " ,
null
),
array ( " RRULE:FREQ=YEARLY;UNTIL=20170202T090000Z " ,
null
),
// just the RRULE property
array ( 'FREQ=DAILY' ,
null
),
array ( " FREQ=YEARLY;UNTIL=20170202 " ,
null
),
array ( " FREQ=YEARLY;UNTIL=20170202T090000 " ,
null
),
array ( " FREQ=YEARLY;UNTIL=20170202T090000Z " ,
null
),
2019-09-01 14:08:55 +02:00
// non-standard timezones
'Windows timezone' => [
' DTSTART ; TZID = W . Europe Standard Time : 19970901 T090000
RRULE : FREQ = DAILY ; COUNT = 3 ' ,
[
date_create ( '1997-09-01 09:00:00' , new DateTimeZone ( 'Europe/Berlin' )),
date_create ( '1997-09-02 09:00:00' , new DateTimeZone ( 'Europe/Berlin' )),
date_create ( '1997-09-03 09:00:00' , new DateTimeZone ( 'Europe/Berlin' )),
]
],
2015-07-08 11:40:45 +02:00
);
}
/**
* @ dataProvider rfcStrings
*/
2017-02-02 18:30:10 +01:00
public function testRfcStringParser ( $str , $occurrences )
2015-07-08 11:40:45 +02:00
{
$rule = new RRule ( $str );
2016-06-30 10:51:47 +02:00
2021-05-07 14:59:35 +02:00
// test that parsing the string produces the same result
2015-07-08 11:40:45 +02:00
// as generating the string from a rule
$this -> assertEquals ( $rule , new RRule ( $rule -> rfcString ()));
2017-02-02 18:30:10 +01:00
2019-01-14 14:09:43 +01:00
if ( $occurrences ) {
2017-02-02 18:30:10 +01:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences ());
}
}
2019-10-05 02:21:40 +02:00
2017-05-06 14:35:15 +02:00
public function testRfcStringParserWithDtStart ()
{
$rrule = new RRule ( 'RRULE:FREQ=YEARLY' );
2017-05-07 15:02:05 +02:00
$this -> assertEquals ( date_create () -> format ( 'Y-m-d' ), $rrule [ 0 ] -> format ( 'Y-m-d' ));
2017-05-06 14:35:15 +02:00
$rrule = new RRule ( 'RRULE:FREQ=YEARLY' , date_create ( '2017-01-01' ));
2017-05-07 15:02:05 +02:00
$this -> assertEquals ( '2017-01-01' , $rrule [ 0 ] -> format ( 'Y-m-d' ));
2017-05-06 14:35:15 +02:00
$rrule = new RRule ( 'RRULE:FREQ=YEARLY' , '2017-01-01' );
2017-05-07 15:02:05 +02:00
$this -> assertEquals ( '2017-01-01' , $rrule [ 0 ] -> format ( 'Y-m-d' ));
2018-05-15 18:41:41 +02:00
}
2017-05-06 14:35:15 +02:00
2018-05-15 18:41:41 +02:00
public function testRfcStringParserWithMultipleDtStart ()
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
$this -> expectExceptionMessage ( " Too many DTSTART properties (there can be only one) " );
2018-05-15 18:41:41 +02:00
$rrule = new RRule ( " DTSTART:19970512 \n RRULE:FREQ=YEARLY " , date_create ( '2017-01-01' ));
2017-05-06 14:35:15 +02:00
}
2017-02-02 18:30:10 +01:00
/**
* @ see https :// github . com / rlanvin / php - rrule / issues / 25
*/
public function quirkyRfcStrings ()
{
return array (
2021-05-07 14:59:35 +02:00
array ( 'DTSTART=20160202T000000Z;FREQ=DAILY;UNTIL=20160205T000000Z' ,
2017-02-02 18:30:10 +01:00
array (
date_create ( '2016-02-02' , new DateTimeZone ( 'UTC' )),
date_create ( '2016-02-03' , new DateTimeZone ( 'UTC' )),
date_create ( '2016-02-04' , new DateTimeZone ( 'UTC' )),
date_create ( '2016-02-05' , new DateTimeZone ( 'UTC' ))
)
),
2021-05-07 14:59:35 +02:00
array ( 'RRULE:DTSTART=20160202T000000Z;FREQ=DAILY;UNTIL=20160205T000000Z' ,
2017-02-02 18:30:10 +01:00
array (
date_create ( '2016-02-02' , new DateTimeZone ( 'UTC' )),
date_create ( '2016-02-03' , new DateTimeZone ( 'UTC' )),
date_create ( '2016-02-04' , new DateTimeZone ( 'UTC' )),
date_create ( '2016-02-05' , new DateTimeZone ( 'UTC' ))
)
)
);
}
2021-05-07 14:59:35 +02:00
/**
2017-02-02 18:30:10 +01:00
* @ dataProvider quirkyRfcStrings
*/
public function testQuirkyRfcStringsParserNotice ( $str , $occurrences )
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \PHPUnit\Framework\Error\Notice :: class );
2017-02-02 18:30:10 +01:00
$rule = new RRule ( $str );
}
/**
* @ dataProvider quirkyRfcStrings
*/
public function testQuirkyRfcStringsParser ( $str , $occurrences )
{
$rule = @ new RRule ( $str );
2019-01-14 14:09:43 +01:00
if ( $occurrences ) {
2017-05-07 15:02:05 +02:00
$this -> assertEquals ( $occurrences , $rule -> getOccurrences (), '' , 1 );
2017-02-02 18:30:10 +01:00
}
2015-07-08 11:40:45 +02:00
}
2016-06-30 10:51:47 +02:00
public function invalidRfcStrings ()
{
return array (
2016-11-11 19:20:09 +01:00
// plain invalid strings
array ( 'foobar' ),
array ( 'blah=blah=blah' ),
2016-06-30 10:51:47 +02:00
// test invalid date formats
array ( ' DTSTART : 2006 - 06 - 24
RRULE : FREQ = DAILY ' ),
array ( ' DTSTART : 2006 - 06 - 24 12 : 00 : 00
RRULE : FREQ = DAILY ' ),
array ( ' DTSTART : 20060624
RRULE : FREQ = DAILY ; UNTIL = 2006 - 06 - 24 ' ),
2017-02-02 18:30:10 +01:00
// multiple dtstart
array ( ' DTSTART : 20060624
RRULE : DTSTART = 20060630 ; FREQ = DAILY ; UNTIL = 20060624 ' ),
2016-06-30 10:51:47 +02:00
// test combinations of DTSTART and UNTIL which are invalid
array ( ' DTSTART ; TZID = Australia / Sydney : 20160624
RRULE : FREQ = DAILY ; INTERVAL = 1 ; UNTIL = 20160628 ' ),
array ( ' DTSTART ; TZID = America / New_York : 19970512 T090000Z
RRULE : FREQ = YEARLY ' ),
array ( ' DTSTART ; TZID = America / New_York : 19970512 T090000
RRULE : FREQ = YEARLY ; UNTIL = 19970512 ' ),
array ( ' DTSTART ; TZID = America / New_York : 19970512 T090000
RRULE : FREQ = YEARLY ; UNTIL = 19970512 T090000 ' ),
array ( ' DTSTART : 19970512 T090000
RRULE : FREQ = YEARLY ; UNTIL = 19970512 ' ),
array ( ' DTSTART : 19970512 T090000Z
RRULE : FREQ = YEARLY ; UNTIL = 19970512 ' ),
array ( ' DTSTART : 19970512
RRULE : FREQ = YEARLY ; UNTIL = 19970512 T090000 ' ),
array ( ' DTSTART : 19970512
RRULE : FREQ = YEARLY ; UNTIL = 19970512 T090000Z ' ),
2017-04-11 15:20:42 +02:00
// missing RRULE
array ( " DTSTART:20060624 \n FREQ=DAILY " ),
// multiple RRULE or DTSTART
array ( " DTSTART:20060624 \n RRULE:FREQ=DAILY \n RRULE:FREQ=YEARLY " ),
array ( " DTSTART:20060624 \n DTSTART:20060624 \n RRULE:FREQ=YEARLY " ),
// properties for Rset
array ( " DTSTART:20060624 \n RRULE:FREQ=DAILY \n EXRULE:FREQ=YEARLY " ),
2016-06-30 10:51:47 +02:00
);
}
/**
* @ dataProvider invalidRfcStrings
*/
public function testInvalidRfcStrings ( $str )
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2016-06-30 10:51:47 +02:00
$rule = new RRule ( $str );
}
2016-06-30 12:27:06 +02:00
public function testRfcStringWithUTC ()
{
$rule = new RRule ( ' DTSTART : 19970512 T090000Z
RRULE : FREQ = YEARLY ' );
$this -> assertEquals ( " DTSTART:19970512T090000Z \n RRULE:FREQ=YEARLY " , $rule -> rfcString ());
}
2016-08-07 13:56:39 +02:00
/**
* @ see https :// github . com / rlanvin / php - rrule / issues / 15
*/
public function testRfcStsringsWithTimestamp ()
{
$rrule = new RRule ( array (
" freq " => " WEEKLY " ,
" dtstart " => 1470323171 ,
" interval " => 1
));
$str = $rrule -> rfcString ();
$new_rrule = new RRule ( $str );
2018-05-15 18:41:41 +02:00
$this -> assertInstanceOf ( 'RRule\RRule' , $new_rrule );
2016-08-07 13:56:39 +02:00
}
2017-03-29 15:27:26 +02:00
2016-08-07 13:56:39 +02:00
public function testUnsupportedTimezoneConvertedToUtc ()
{
2019-09-01 14:08:55 +02:00
$date = new DateTime ( '2016-07-08 12:00:00' , new DateTimeZone ( '+06:00' ));
$rrule = new RRule ( array (
" freq " => " WEEKLY " ,
" dtstart " => $date ,
" interval " => 1
));
$str = $rrule -> rfcString ();
$this -> assertTrue ( strpos ( $str , '20160708T060000Z' ) !== false );
$new_rrule = new RRule ( $str );
2016-08-07 13:56:39 +02:00
}
2017-03-29 15:27:26 +02:00
2016-06-30 13:03:10 +02:00
public function rfcStringsWithoutTimezone ()
{
return array (
array (
" DTSTART;TZID=America/New_York:19970901T090000 \n RRULE:FREQ=DAILY " ,
" DTSTART:19970901T090000 \n RRULE:FREQ=DAILY " ,
),
array (
" DTSTART;TZID=Europe/Paris:19970901T090000 \n RRULE:FREQ=DAILY;UNTIL=19970902T070000Z " ,
" DTSTART:19970901T090000 \n RRULE:FREQ=DAILY;UNTIL=19970902T090000 " ,
),
);
}
/**
* @ dataProvider rfcStringsWithoutTimezone
*/
public function testRfcStringWithoutTimezone ( $str , $expected_str )
{
$rule = new RRule ( $str );
$this -> assertEquals ( $expected_str , $rule -> rfcString ( false ));
}
2016-08-17 23:14:38 +02:00
public function rfcStringsGenerated ()
{
return array (
array (
array (
'FREQ' => RRule :: YEARLY ,
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=YEARLY "
),
array (
array (
'FREQ' => RRule :: MONTHLY ,
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=MONTHLY "
),
array (
array (
'FREQ' => RRule :: WEEKLY ,
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=WEEKLY "
),
array (
array (
'FREQ' => RRule :: DAILY ,
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=DAILY "
),
array (
array (
'FREQ' => RRule :: HOURLY ,
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=HOURLY "
),
array (
array (
'FREQ' => RRule :: MINUTELY ,
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=MINUTELY "
),
array (
array (
'FREQ' => RRule :: SECONDLY ,
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=SECONDLY "
),
2018-04-13 11:03:07 +02:00
array (
array (
'FREQ' => RRule :: SECONDLY ,
'BYMINUTE' => 0 ,
'BYHOUR' => 0 ,
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=SECONDLY;BYMINUTE=0;BYHOUR=0 "
),
2019-10-05 02:21:40 +02:00
'with a value as an array' => [
array (
'FREQ' => RRule :: SECONDLY ,
'BYMINUTE' => 0 ,
'BYHOUR' => [ 0 , 1 ],
'DTSTART' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
),
" DTSTART;TZID=Australia/Sydney:20150701T090000 \n RRULE:FREQ=SECONDLY;BYMINUTE=0;BYHOUR=0,1 "
],
2016-08-17 23:14:38 +02:00
);
}
/**
* @ dataProvider rfcStringsGenerated
*/
public function testRfcStringsGenerated ( $params , $expected_str )
{
$rule = new RRule ( $params );
$this -> assertEquals ( $expected_str , $rule -> rfcString ());
}
2019-10-05 02:21:40 +02:00
public function testMagicStringMethod ()
{
$rule = new RRule ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
RRULE : FREQ = HOURLY ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTH = 1 ; BYHOUR = 1 ' );
$this -> assertEquals ( $rule -> rfcString (), ( string ) $rule );
}
2017-04-11 17:44:50 +02:00
///////////////////////////////////////////////////////////////////////////////
// RFC Factory method
public function rfcStringsForFactory ()
{
return array (
array ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
RRULE : FREQ = HOURLY ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ; BYMONTH = 1 ; BYHOUR = 1 ' ,
'\RRule\RRule'
),
array ( ' DTSTART ; TZID = America / New_York : 19970512 T090000
RRULE : FREQ = YEARLY ; BYYEARDAY = 1 , - 1 , 10 , - 50 ; BYDAY = MO ' ,
'\RRule\RRule'
),
array ( ' DTSTART : 19970512 T090000Z
RRULE : FREQ = YEARLY ' ,
'\RRule\RRule'
),
array ( ' DTSTART : 19970512 T090000
RRULE : FREQ = YEARLY ' ,
'\RRule\RRule'
),
array ( ' DTSTART : 19970512
RRULE : FREQ = YEARLY ' ,
'\RRule\RRule'
),
// empty lines
array ( " \n DTSTART:19970512 \n RRULE:FREQ=YEARLY;COUNT=3 \n \n " ,
'\RRule\RRule'
),
2019-10-05 02:21:40 +02:00
'no DTSTART' => [
" RRULE:FREQ=YEARLY;COUNT=3 " ,
2017-04-11 17:44:50 +02:00
'\RRule\RRule'
2019-10-05 02:21:40 +02:00
],
2017-04-11 17:44:50 +02:00
array (
" DTSTART;TZID=America/New_York:19970901T090000 \n RRULE:FREQ=DAILY \n EXRULE:FREQ=YEARLY \n EXDATE;TZID=America/New_York:19970902T090000 " ,
'\RRule\RSet'
2019-09-01 20:50:21 +02:00
),
2019-10-05 02:21:40 +02:00
'no rrule' => [
'EXRULE:FREQ=DAILY;COUNT=3' ,
\RRule\RRule :: class
],
2019-09-01 20:50:21 +02:00
'lowercase rrule' => [
" rrule:freq=yearly;count=3 " ,
" \R Rule \R Rule "
],
'lowercase rset with 2 rrules' => [
" rrule:freq=yearly;count=3 \n rrule:freq=monthly " ,
" \R Rule \R Set "
]
2017-04-11 17:44:50 +02:00
);
}
/**
* @ dataProvider rfcStringsForFactory
*/
public function testCreateFromRfcString ( $string , $expected_class )
{
$object = RRule :: createFromRfcString ( $string );
$this -> assertInstanceOf ( $expected_class , $object );
}
/**
* @ dataProvider rfcStringsForFactory
*/
public function testCreateFromRfcStringForceRSet ( $string )
{
$object = RRule :: createFromRfcString ( $string , true );
$this -> assertInstanceOf ( '\RRule\RSet' , $object );
}
2022-05-03 15:11:22 +02:00
public function testCreateFromRfcStringDoesntChangeCase ()
{
$str = " DTSTART;TZID=Europe/Paris:20200929T000000 \n RRULE:FREQ=DAILY;BYSECOND=0;BYMINUTE=0;BYHOUR=9 " ;
$rule = RRule :: createFromRfcString ( $str );
$this -> assertEquals ( $str , $rule -> rfcString ());
}
2016-06-30 10:51:47 +02:00
///////////////////////////////////////////////////////////////////////////////
// Timezone
2016-03-11 10:02:40 +01:00
public function testTimezoneIsKeptIdentical ()
{
$rrule = new RRule ( array (
'freq' => 'yearly' ,
'bymonthday' => '31,30' ,
'count' => 3 ,
'dtstart' => date_create ( '2015-07-01 09:00:00' )
));
$this -> assertEquals ( date_create ( '2015-07-30 09:00:00' ), $rrule [ 0 ]);
$rrule = new RRule ( array (
'freq' => 'yearly' ,
'bymonthday' => '31,30' ,
'count' => 3 ,
'dtstart' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
));
$this -> assertEquals ( date_create ( '2015-07-30 09:00:00' , new DateTimeZone ( 'Australia/Sydney' )), $rrule [ 0 ]);
$rrule = new RRule ( array (
'freq' => 'yearly' ,
'bymonthday' => '31,30' ,
'count' => 3 ,
'dtstart' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Europe/Helsinki' ))
));
$this -> assertEquals ( date_create ( '2015-07-30 09:00:00' , new DateTimeZone ( 'Europe/Helsinki' )), $rrule [ 0 ]);
// using a rfc string
$rrule = new RRule ( ' DTSTART ; TZID = America / New_York : 19970901 T090000
RRULE : FREQ = DAILY ; UNTIL = 19971224 T000000Z ; WKST = SU ; BYDAY = MO , WE , FR ' );
$this -> assertEquals ( date_create ( '1997-09-01 09:00:00' , new DateTimeZone ( 'America/New_York' )), $rrule [ 0 ]);
}
2016-03-21 21:43:38 +01:00
2016-03-23 11:03:43 +01:00
public function testOccursAtTakeTimezoneIntoAccount ()
{
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 365 ,
'dtstart' => date_create ( '2015-07-01 09:00:00' )
));
$this -> assertTrue ( $rrule -> occursAt ( '2015-07-02 09:00:00' ), 'When timezone is not specified, it takes the default timezone' );
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 365 ,
'dtstart' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))
));
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-07-02 09:00:00' , new DateTimeZone ( 'Australia/Sydney' ))));
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-07-01 23:00:00' , new DateTimeZone ( 'UTC' ))), 'Timezone is converted for comparison (cached)' );
$rrule -> clearCache ();
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-07-01 23:00:00' , new DateTimeZone ( 'UTC' ))), 'Timezone is converted for comparison (uncached)' );
2016-03-23 11:03:43 +01:00
2016-03-24 08:22:32 +01:00
$rrule -> clearCache ();
2016-03-23 11:03:43 +01:00
$this -> assertFalse ( $rrule -> occursAt ( '2015-07-02 09:00:00' ), 'When passed a string, default timezone is used for creating the DateTime' );
2016-03-24 08:22:32 +01:00
$rrule -> clearCache ();
$this -> assertTrue ( $rrule -> occursAt ( 'Wed, 01 Jul 2015 09:00:00 +1000' ), 'When passed a string with timezone, timezone is kept (uncached)' );
$this -> assertTrue ( $rrule -> occursAt ( 'Wed, 01 Jul 2015 09:00:00 +1000' ), 'When passed a string with timezone, timezone is kept (cached)' );
$rrule -> clearCache ();
$this -> assertTrue ( $rrule -> occursAt ( '2015-07-01T09:00:00+10:00' ), 'When passed a string with timezone, timezone is kept (uncached)' );
$this -> assertTrue ( $rrule -> occursAt ( '2015-07-01T09:00:00+10:00' ), 'When passed a string with timezone, timezone is kept (cached)' );
2016-03-23 11:03:43 +01:00
// test with DST
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 365 ,
'dtstart' => date_create ( '2015-07-01 09:00:00' , new DateTimeZone ( 'Europe/Helsinki' ))
));
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-07-02 09:00:00' , new DateTimeZone ( 'Europe/Helsinki' ))));
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-07-02 06:00:00' , new DateTimeZone ( 'UTC' ))), 'During summer time, Europe/Helsinki is UTC+3 (cached)' );
$rrule -> clearCache ();
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-07-02 06:00:00' , new DateTimeZone ( 'UTC' ))), 'During summer time, Europe/Helsinki is UTC+3 (uncached)' );
2016-03-23 11:03:43 +01:00
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-12-02 09:00:00' , new DateTimeZone ( 'Europe/Helsinki' ))));
2016-03-24 08:22:32 +01:00
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-12-02 07:00:00' , new DateTimeZone ( 'UTC' ))), 'During winter time, Europe/Helsinki is UTC+2 (cached)' );
$rrule -> clearCache ();
$this -> assertTrue ( $rrule -> occursAt ( date_create ( '2015-12-02 07:00:00' , new DateTimeZone ( 'UTC' ))), 'During winter time, Europe/Helsinki is UTC+2 (uncached)' );
2016-03-23 11:03:43 +01:00
}
2016-06-30 10:51:47 +02:00
public function rulesWithMismatchedTimezones ()
{
return array (
array (
array ( 'DTSTART' => new DateTime ( '20160624Z' ), 'FREQ' => 'DAILY' , 'INTERVAL' => 1 , 'UNTIL' => '20160628' ),
array (
date_create ( '20160624Z' ),
date_create ( '20160625Z' ),
date_create ( '20160626Z' ),
date_create ( '20160627Z' ),
// date_create('20160628Z') // will not return this due to timezone mismatch (unless default timezone is utc)
)
),
array (
array ( 'DTSTART' => new DateTime ( '20160624Z' ), 'FREQ' => 'DAILY' , 'INTERVAL' => 1 , 'UNTIL' => '28-06-2016' ),
array (
date_create ( '20160624Z' ),
date_create ( '20160625Z' ),
date_create ( '20160626Z' ),
date_create ( '20160627Z' ),
// date_create('20160628Z') // will not return this due to timezone mismatch (unless default timezone is utc)
)
),
array (
array ( 'DTSTART' => new DateTime ( '20160624Z' ), 'FREQ' => 'DAILY' , 'INTERVAL' => 1 , 'UNTIL' => new DateTime ( '20160628' , new DateTimeZone ( 'Europe/Paris' ))),
array (
date_create ( '20160624Z' ),
date_create ( '20160625Z' ),
date_create ( '20160626Z' ),
date_create ( '20160627Z' ),
// date_create('20160628Z') // will not return this due to timezone mismatch (unless default timezone is utc)
)
)
);
}
/**
* Test bug issue #13
* @ see https :// github . com / rlanvin / php - rrule / issues / 13
* @ dataProvider rulesWithMismatchedTimezones
*/
public function testRulesWithMismatchedTimezones ( $rule , $occurrences )
{
$rrule = new RRule ( $rule );
$this -> assertEquals ( $occurrences , $rrule -> getOccurrences (), 'Mismatched timezones makes for strange results' );
}
///////////////////////////////////////////////////////////////////////////////
// Other tests
2019-10-05 02:21:40 +02:00
public function invalidConstructorParameters ()
{
return [
[ new stdClass , null ],
[ true , null ],
[ 1 , null ],
[ 4.2 , null ],
'dtstart optional parameter only for string rules' => [[ 'FREQ' => 'DAILY' ], new DateTime ()]
];
}
/**
* @ dataProvider invalidConstructorParameters
*/
public function testConstructorDoesntAcceptInvalidTypes ( $parts , $dtstart )
{
$this -> expectException ( \InvalidArgumentException :: class );
new RRule ( $dtstart , $dtstart );
}
2016-03-21 22:56:35 +01:00
public function testIsFinite ()
{
$rrule = new RRule ( array (
'freq' => 'yearly'
));
$this -> assertTrue ( $rrule -> isInfinite ());
$this -> assertFalse ( $rrule -> isFinite ());
$rrule = new RRule ( array (
'freq' => 'yearly' ,
'count' => 10
));
$this -> assertFalse ( $rrule -> isInfinite ());
$this -> assertTrue ( $rrule -> isFinite ());
}
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 ));
}
2016-03-23 14:59:30 +01:00
public function testDateTimeMutableReferenceBug ()
{
2016-03-24 08:27:25 +01:00
$date = date_create ( '2007-01-01' );
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 10 ,
'dtstart' => $date
));
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ]);
$date -> modify ( '+1day' );
$rrule -> clearCache ();
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible of dtstart' );
2016-03-23 14:59:30 +01:00
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 10 ,
'dtstart' => '2007-01-01'
));
// offsetGet
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ]);
$rrule [ 0 ] -> modify ( '+1 day' );
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible with offsetGet (uncached)' );
$rrule [ 0 ] -> modify ( '+1 day' );
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible with offsetGet (cached)' );
// iterate
$rrule -> clearCache ();
2019-01-14 14:09:43 +01:00
foreach ( $rrule as $occurrence ) {
2016-03-23 14:59:30 +01:00
break ;
}
$this -> assertEquals ( date_create ( '2007-01-01' ), $occurrence );
$occurrence -> modify ( '+1 day' );
2021-05-07 14:59:35 +02:00
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible with foreach (uncached)' );
2016-03-23 14:59:30 +01:00
2019-01-14 14:09:43 +01:00
foreach ( $rrule as $occurrence ) {
2016-03-23 14:59:30 +01:00
break ;
}
$this -> assertEquals ( date_create ( '2007-01-01' ), $occurrence );
$occurrence -> modify ( '+1 day' );
2021-05-07 14:59:35 +02:00
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible with foreach (cached)' );
2016-03-23 14:59:30 +01:00
2021-01-09 14:18:28 +01:00
// getOccurrences
2016-03-23 14:59:30 +01:00
$occurrences = $rrule -> getOccurrences ();
$this -> assertEquals ( date_create ( '2007-01-01' ), $occurrences [ 0 ]);
$occurrences [ 0 ] -> modify ( '+1 day' );
$this -> assertEquals ( date_create ( '2007-01-02' ), $occurrences [ 0 ]);
2021-01-09 14:18:28 +01:00
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible with getOccurrences (uncached version)' );
2016-03-23 14:59:30 +01:00
$occurrences = $rrule -> getOccurrences ();
$this -> assertEquals ( date_create ( '2007-01-01' ), $occurrences [ 0 ]);
$occurrences [ 0 ] -> modify ( '+1 day' );
$this -> assertEquals ( date_create ( '2007-01-02' ), $occurrences [ 0 ]);
2021-01-09 14:18:28 +01:00
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible with getOccurrences (cached version)' );
2016-03-23 14:59:30 +01:00
// getOccurrencesBetween
$occurrences = $rrule -> getOccurrencesBetween ( null , null );
$this -> assertEquals ( date_create ( '2007-01-01' ), $occurrences [ 0 ]);
$occurrences [ 0 ] -> modify ( '+1 day' );
$this -> assertEquals ( date_create ( '2007-01-02' ), $occurrences [ 0 ]);
2021-01-09 14:18:28 +01:00
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible with getOccurrences (uncached version)' );
2016-03-23 14:59:30 +01:00
$occurrences = $rrule -> getOccurrencesBetween ( null , null );
$this -> assertEquals ( date_create ( '2007-01-01' ), $occurrences [ 0 ]);
$occurrences [ 0 ] -> modify ( '+1 day' );
$this -> assertEquals ( date_create ( '2007-01-02' ), $occurrences [ 0 ]);
2021-01-09 14:18:28 +01:00
$this -> assertEquals ( date_create ( '2007-01-01' ), $rrule [ 0 ], 'No modification possible with getOccurrences (cached version)' );
2016-08-31 14:56:39 +02:00
}
2016-03-23 14:59:30 +01:00
2016-08-31 14:56:39 +02:00
public function testGetRule ()
{
$array = array (
2017-01-06 15:42:00 +01:00
'FREQ' => 'YEARLY' ,
'DTSTART' => '2016-01-01'
2016-08-31 14:56:39 +02:00
);
$rrule = new RRule ( $array );
2022-08-21 11:08:21 +02:00
$this -> assertInternalType ( 'array' , $rrule -> getRule ());
2017-01-06 15:42:00 +01:00
$rule = $rrule -> getRule ();
$this -> assertEquals ( 'YEARLY' , $rule [ 'FREQ' ]);
2022-08-21 11:08:21 +02:00
$this -> assertInternalType ( 'string' , $rule [ 'DTSTART' ]);
2017-01-06 15:42:00 +01:00
$rrule = new RRule ( " DTSTART;TZID=America/New_York:19970901T090000 \n RRULE:FREQ=HOURLY;UNTIL=19971224T000000Z;WKST=SU;BYDAY=MO,WE,FR;BYMONTH=1;BYHOUR=1 " );
$rule = $rrule -> getRule ();
$this -> assertEquals ( 'HOURLY' , $rule [ 'FREQ' ]);
$this -> assertTrue ( $rule [ 'DTSTART' ] instanceof \DateTime );
$rrule = new RRule ( " DTSTART:19970901 \n RRULE:FREQ=DAILY;UNTIL=19971224;WKST=SU;BYDAY=MO,WE,FR;BYMONTH=1 " );
$rule = $rrule -> getRule ();
$this -> assertEquals ( 'DAILY' , $rule [ 'FREQ' ]);
$this -> assertTrue ( $rule [ 'DTSTART' ] instanceof \DateTime );
2016-03-23 14:59:30 +01:00
}
2017-01-06 15:16:44 +01:00
2020-12-09 08:51:26 +01:00
/**
* Test Bug #90
* @ see https :// github . com / rlanvin / php - rrule / issues / 90
*/
public function testDateImmutable ()
{
$dtstart_immutable = \DateTimeImmutable :: createFromFormat ( 'Y-m-d H:i' , '2021-01-08 08:00' );
//$dtstart_mutable = \DateTime::createFromFormat('Y-m-d H:i', '2021-01-08 08:00');
$rrule = new RRule ([
'BYDAY' => [ 'MO' , 'WE' , 'FR' ],
'FREQ' => 'WEEKLY' ,
'WKST' => 'SU' ,
'DTSTART' => $dtstart_immutable ,
]);
$start = \DateTimeImmutable :: createFromFormat ( 'Y-m-d' , '2020-01-01' );
$end = \DateTimeImmutable :: createFromFormat ( 'Y-m-d' , '2021-12-31' );
$occurrences = $rrule -> getOccurrencesBetween ( $start , $end , 10 );
$this -> assertEquals ([
new DateTime ( 'Friday, January 8, 2021 08:00' ),
new DateTime ( 'Monday, January 11, 2021 08:00' ),
new DateTime ( 'Wednesday, January 13, 2021 08:00' ),
new DateTime ( 'Friday, January 15, 2021 08:00' ),
new DateTime ( 'Monday, January 18, 2021 08:00' ),
new DateTime ( 'Wednesday, January 20, 2021 08:00' ),
new DateTime ( 'Friday, January 22, 2021 08:00' ),
new DateTime ( 'Monday, January 25, 2021 08:00' ),
new DateTime ( 'Wednesday, January 27, 2021 08:00' ),
new DateTime ( 'Friday, January 29, 2021 08:00' )
], $occurrences , 'DateTimeImmutable produces valid results' );
}
2022-04-22 10:16:25 +02:00
/**
* Test bug #104
* @ see https :// github . com / rlanvin / php - rrule / issues / 104
*/
public function testMicrosecondsAreRemovedFromInput ()
{
$dtstart = '2022-04-22 12:00:00.5' ;
$rule = new RRule ([
'dtstart' => $dtstart ,
'freq' => 'daily' ,
'interval' => 1 ,
'count' => 1
]);
$this -> assertTrue ( $rule -> occursAt ( '2022-04-22 12:00:00' ));
$this -> assertTrue ( $rule -> occursAt ( '2022-04-22 12:00:00.5' ));
$this -> assertEquals ( date_create ( '2022-04-22 12:00:00' ), $rule [ 0 ]);
}
2017-01-06 15:16:44 +01:00
///////////////////////////////////////////////////////////////////////////////
// Array access and countable interfaces
public function testCountable ()
{
$rrule = new RRule ( array (
'freq' => 'yearly' ,
'count' => 10
));
$this -> assertEquals ( 10 , count ( $rrule ));
}
2019-10-05 02:21:40 +02:00
public function testCannotCountInfinite ()
{
$rrule = new RRule ( array (
'freq' => 'yearly'
));
2020-12-09 22:26:35 +01:00
$this -> expectException ( \LogicException :: class );
2019-10-05 02:21:40 +02:00
count ( $rrule );
}
2017-01-06 15:16:44 +01:00
public function testOffsetExists ()
{
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 3 ,
'byday' => 'TU,TH' ,
'dtstart' => '2007-01-01'
));
$this -> assertTrue ( isset ( $rrule [ 0 ]));
$this -> assertTrue ( isset ( $rrule [ 1 ]));
$this -> assertTrue ( isset ( $rrule [ 2 ]));
$this -> assertFalse ( isset ( $rrule [ 3 ]));
}
public function testOffsetGet ()
{
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 3 ,
'byday' => 'TU,TH' ,
'dtstart' => '2007-01-01'
));
$this -> assertEquals ( date_create ( '2007-01-02' ), $rrule [ 0 ]);
$this -> assertEquals ( date_create ( '2007-01-02' ), $rrule [ '0' ]);
$this -> assertEquals ( date_create ( '2007-01-04' ), $rrule [ 1 ]);
$this -> assertEquals ( date_create ( '2007-01-04' ), $rrule [ '1' ]);
$this -> assertEquals ( date_create ( '2007-01-09' ), $rrule [ 2 ]);
$this -> assertEquals ( null , $rrule [ 4 ]);
$this -> assertEquals ( null , $rrule [ '4' ]);
}
2019-10-05 02:21:40 +02:00
public function testOffsetSetUnsupported ()
{
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 3 ,
'byday' => 'TU,TH' ,
'dtstart' => '2007-01-01'
));
2020-12-09 22:26:35 +01:00
$this -> expectException ( \LogicException :: class );
2019-10-05 02:21:40 +02:00
$rrule [] = 'blah' ;
}
public function testOffsetUnsetUnsupported ()
{
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 3 ,
'byday' => 'TU,TH' ,
'dtstart' => '2007-01-01'
));
2020-12-09 22:26:35 +01:00
$this -> expectException ( \LogicException :: class );
2019-10-05 02:21:40 +02:00
unset ( $rrule [ 0 ]);
}
2017-01-06 15:16:44 +01:00
public function illegalOffsets ()
{
return array (
array ( 'dtstart' ),
array ( '1dtstart' ),
array ( array ()),
array ( 1.1 ),
array ( - 1 ),
array ( null ),
array ( new stdClass ())
);
}
/**
* @ dataProvider illegalOffsets
*/
public function testOffsetGetInvalidArgument ( $offset )
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2017-01-06 15:16:44 +01:00
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 3 ,
'byday' => 'TU,TH' ,
'dtstart' => '2007-01-01'
));
$rrule [ $offset ];
}
2016-04-03 15:41:30 +02:00
2016-04-04 15:34:57 +02:00
///////////////////////////////////////////////////////////////////////////////
// Human readable string conversion
public function validLocales ()
2016-04-03 15:41:30 +02:00
{
return array (
2017-02-02 23:35:09 +01:00
// locale | result expected with intl | result expected without intl
2016-04-04 15:34:57 +02:00
// 2 characters language code
2017-02-02 23:35:09 +01:00
array ( 'en' , array ( 'en' ), array ( 'en' )),
array ( 'fr' , array ( 'fr' ), array ( 'fr' )),
2021-05-07 14:59:35 +02:00
array ( 'sv' , array ( 'sv' ), array ( 'sv' )),
2016-04-04 15:34:57 +02:00
// with region and underscore
2017-02-02 23:35:09 +01:00
array ( 'en_US' , array ( 'en' , 'en_US' ), array ( 'en' , 'en_US' )),
array ( 'en_US.utf-8' , array ( 'en' , 'en_US' ), array ( 'en' , 'en_US' )),
2021-05-07 14:59:35 +02:00
array ( 'en_US_POSIX' , array ( 'en' , 'en_US' ), array ( 'en' , 'en_US' )),
array ( 'sv_SE' , array ( 'sv' , 'sv_SE' ), array ( 'sv' , 'sv_SE' )),
// case insentitive
2017-02-02 23:35:09 +01:00
array ( 'en_sg' , array ( 'en' , 'en_SG' ), array ( 'en' , 'en_SG' )),
2021-05-07 14:59:35 +02:00
array ( 'sv_se' , array ( 'sv' , 'sv_SE' ), array ( 'sv' , 'sv_SE' )),
2016-04-04 15:34:57 +02:00
// with a dash
2017-02-02 23:35:09 +01:00
array ( 'en-US' , array ( 'en' , 'en_US' ), array ( 'en' , 'en_US' )),
array ( 'zh-Hant-TW' , array ( 'zh' , 'zh_TW' ), array ( 'zh' , 'zh_TW' )), // real locale is zh-Hant-TW, but since we don't have a "zh" file, we just use "en" for the test
2021-05-07 14:59:35 +02:00
array ( 'sv-SE' , array ( 'sv' , 'sv_SE' ), array ( 'sv' , 'sv_SE' )),
2017-02-02 23:35:09 +01:00
// invalid
array ( 'eng' , array ( 'en' ), false ),
array ( 'invalid' , array ( 'invalid' ), false ),
array ( 'en_US._wr!ng' , array ( 'en' , 'en_US' ), false ),
2016-04-03 15:41:30 +02:00
);
}
/**
2016-04-04 15:34:57 +02:00
* Test that RRule :: i18nLoad () does not throw an exception with valid locales .
2016-04-03 15:41:30 +02:00
*
2016-04-04 15:34:57 +02:00
* @ dataProvider validLocales
2016-04-03 15:41:30 +02:00
*/
2017-02-02 23:35:09 +01:00
public function testI18nFilesToLoadWithIntl ( $locale , $files )
2016-04-04 15:34:57 +02:00
{
2020-02-24 17:39:41 +01:00
if ( ! extension_loaded ( 'intl' )) {
$this -> markTestSkipped ( 'intl extension is not loaded' );
}
2019-01-13 11:47:43 +01:00
$reflector = new ReflectionClass ( 'RRule\RRule' );
$method = $reflector -> getMethod ( 'i18nFilesToLoad' );
$method -> setAccessible ( true );
2019-01-14 14:09:43 +01:00
if ( ! $files ) {
2017-02-02 23:35:09 +01:00
try {
2019-01-13 11:47:43 +01:00
$method -> invokeArgs ( null , array ( $locale , true ));
2017-02-02 23:35:09 +01:00
$this -> fail ( 'Expected InvalidArgumentException not thrown (files was ' . json_encode ( $files ) . ')' );
} catch ( \InvalidArgumentException $e ) {
}
}
else {
2019-01-13 11:47:43 +01:00
$this -> assertEquals ( $files , $method -> invokeArgs ( null , array ( $locale , true )));
2017-02-02 23:35:09 +01:00
}
}
/**
* @ dataProvider validLocales
*/
public function testI18nFilesToLoadWithoutIntl ( $locale , $dummy , $files )
{
2019-01-13 11:47:43 +01:00
$reflector = new ReflectionClass ( 'RRule\RRule' );
$method = $reflector -> getMethod ( 'i18nFilesToLoad' );
$method -> setAccessible ( true );
2019-01-14 14:09:43 +01:00
if ( ! $files ) {
2017-02-02 23:35:09 +01:00
try {
2019-01-13 11:47:43 +01:00
$method -> invokeArgs ( null , array ( $locale , false ));
2017-02-02 23:35:09 +01:00
$this -> fail ( 'Expected InvalidArgumentException not thrown (files was ' . json_encode ( $files ) . ')' );
} catch ( \InvalidArgumentException $e ) {
2019-03-17 10:45:34 +01:00
$this -> assertStringStartsWith ( " The locale option does not look like a valid locale: " , $e -> getMessage ());
2017-02-02 23:35:09 +01:00
}
}
else {
2019-01-13 11:47:43 +01:00
$this -> assertEquals ( $files , $method -> invokeArgs ( null , array ( $locale , false )));
2017-02-02 23:35:09 +01:00
}
}
/**
* Locales for which we have a translation
*/
public function validTranslatedLocales ()
{
return array (
array ( 'en' ),
array ( 'en_US' )
);
}
2016-04-04 15:34:57 +02:00
2017-02-02 23:35:09 +01:00
/**
* Test that RRule :: i18nLoad () does not throw an exception with valid locales .
*
* @ dataProvider validTranslatedLocales
*/
public function testI18nLoadWithIntl ( $locale )
{
2020-02-24 17:39:41 +01:00
if ( ! extension_loaded ( 'intl' )) {
$this -> markTestSkipped ( 'intl extension is not loaded' );
}
2016-04-04 15:34:57 +02:00
$reflector = new ReflectionClass ( 'RRule\RRule' );
$method = $reflector -> getMethod ( 'i18nLoad' );
$method -> setAccessible ( true );
2017-02-02 23:35:09 +01:00
$result = $method -> invokeArgs ( null , array ( $locale , null , true ));
2016-04-04 15:34:57 +02:00
$this -> assertNotEmpty ( $result );
}
/**
* Test that the RRule :: i18nLoad () does not fail when provided with valid fallback locales
*
2017-02-02 23:35:09 +01:00
* @ dataProvider validTranslatedLocales
2016-04-04 15:34:57 +02:00
*/
public function testI18nLoadFallback ( $fallback )
2016-04-03 15:41:30 +02:00
{
$reflector = new ReflectionClass ( 'RRule\RRule' );
2016-04-04 15:34:57 +02:00
$method = $reflector -> getMethod ( 'i18nLoad' );
$method -> setAccessible ( true );
2016-04-03 15:41:30 +02:00
2017-02-02 23:35:09 +01:00
$result = $method -> invokeArgs ( null , array ( 'xx' , $fallback ));
2016-04-03 15:41:30 +02:00
$this -> assertNotEmpty ( $result );
}
/**
* Tests that the RRule :: i18nLoad () fails as expected on invalid $locale settings
*/
2017-02-02 23:35:09 +01:00
public function testI18nLoadFailsWithoutIntl ()
2016-04-03 15:41:30 +02:00
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2016-04-03 15:41:30 +02:00
$reflector = new ReflectionClass ( 'RRule\RRule' );
2016-04-04 15:34:57 +02:00
$method = $reflector -> getMethod ( 'i18nLoad' );
$method -> setAccessible ( true );
2017-02-02 23:35:09 +01:00
$method -> invokeArgs ( null , array ( 'invalid' , 'en' , false )); // even with a valid fallback it should fail
2016-04-04 15:34:57 +02:00
}
/**
* Tests that the RRule :: i18nLoad () fails as expected on invalid $fallback settings
*/
2017-02-02 23:35:09 +01:00
public function testI18nLoadFallbackFailsWitoutIntl ()
2016-04-04 15:34:57 +02:00
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \InvalidArgumentException :: class );
2016-04-04 15:34:57 +02:00
$reflector = new ReflectionClass ( 'RRule\RRule' );
$method = $reflector -> getMethod ( 'i18nLoad' );
$method -> setAccessible ( true );
2017-02-02 23:35:09 +01:00
$method -> invokeArgs ( null , array ( 'xx' , 'invalid' , false ));
2016-04-04 15:34:57 +02:00
}
public function testHumanReadableRuntimeException ()
{
2020-12-09 22:26:35 +01:00
$this -> expectException ( \RuntimeException :: class );
2016-04-04 15:34:57 +02:00
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 10 ,
'dtstart' => '2007-01-01'
));
$rrule -> humanReadable ( array (
'locale' => 'xx' ,
'fallback' => 'xx'
2016-06-30 10:51:47 +02:00
)); // the locales are correctly formatted, but not such file exist, so this should throw a RuntimeException
2016-04-04 15:34:57 +02:00
}
2021-05-07 14:59:35 +02:00
/**
2016-04-04 15:34:57 +02:00
* Test that humanReadable works
*/
2017-02-02 23:35:09 +01:00
public function testHumanReadableWithCLocale ()
2016-04-04 15:34:57 +02:00
{
$rrule = new RRule ( array (
'freq' => 'daily' ,
'count' => 10 ,
'dtstart' => '2007-01-01'
));
setlocale ( LC_MESSAGES , 'C' );
$this -> assertNotEmpty ( $rrule -> humanReadable ( array ( 'fallback' => null )), 'C locale is converted to "en"' );
2016-04-03 15:41:30 +02:00
}
2017-02-02 23:35:09 +01:00
public function humanReadableStrings ()
{
return array (
array (
2017-04-11 12:20:20 +02:00
" DTSTART:20170202T000000Z \n RRULE:FREQ=DAILY;UNTIL=20170205T000000Z " ,
2020-02-24 17:39:41 +01:00
[ 'locale' => " en " ],
" daily, starting from 2/2/17, until 2/5/17 " ,
'daily, starting from 2017-02-02 00:00:00, until 2017-02-05 00:00:00' ,
2017-02-02 23:35:09 +01:00
),
2019-01-13 10:29:25 +01:00
array (
" RRULE:FREQ=DAILY;UNTIL=20190405T055959Z " ,
2020-02-24 17:39:41 +01:00
[ 'locale' => " en " ],
2019-01-13 10:29:25 +01:00
" daily, starting from 1/10/19, until 4/5/19 " ,
2020-02-24 17:39:41 +01:00
'daily, starting from 2019-01-10 12:00:00, until 2019-04-05 05:59:59' ,
2019-01-13 10:29:25 +01:00
'2019-01-10T12:00:00-05:00'
),
2017-02-02 23:35:09 +01:00
array (
2017-04-11 12:20:20 +02:00
" DTSTART:20170202T000000Z \n RRULE:FREQ=DAILY;UNTIL=20170205T000000Z " ,
array ( 'locale' => " en_IE " ),
2020-02-24 17:39:41 +01:00
" daily, starting from 02/02/2017, until 05/02/2017 " ,
'daily, starting from 2017-02-02 00:00:00, until 2017-02-05 00:00:00'
2017-03-29 15:20:00 +02:00
),
array (
2017-04-11 12:20:20 +02:00
" DTSTART;TZID=America/New_York:19970901T090000 \n RRULE:FREQ=DAILY;UNTIL=20170205T000000Z " ,
array ( 'locale' => " en_IE " ),
2020-02-24 17:39:41 +01:00
" daily, starting from 01/09/1997, until 04/02/2017 " ,
'daily, starting from 1997-09-01 09:00:00, until 2017-02-05 00:00:00'
2017-04-11 12:20:20 +02:00
),
array (
" DTSTART;TZID=America/New_York:19970901T090000 \n RRULE:FREQ=DAILY;UNTIL=20170205T000000Z " ,
2017-04-11 17:49:46 +02:00
array ( 'locale' => " en_IE " , 'include_start' => false ),
2020-02-24 17:39:41 +01:00
" daily, until 04/02/2017 " ,
'daily, until 2017-02-05 00:00:00'
2017-04-11 12:20:20 +02:00
),
array (
" DTSTART;TZID=America/New_York:19970901T090000 \n RRULE:FREQ=DAILY " ,
array ( 'locale' => " en_IE " , 'explicit_infinite' => false ),
2020-02-24 17:39:41 +01:00
" daily, starting from 01/09/1997 " ,
'daily, starting from 1997-09-01 09:00:00'
2017-04-11 12:20:20 +02:00
),
array (
" DTSTART;TZID=America/New_York:19970901T090000 \n RRULE:FREQ=YEARLY;INTERVAL=2 " ,
array ( 'locale' => " en_IE " , 'explicit_infinite' => false ),
2020-02-24 17:39:41 +01:00
" every 2 years, starting from 01/09/1997 " ,
'every 2 years, starting from 1997-09-01 09:00:00'
2017-04-11 12:20:20 +02:00
),
array (
" FREQ=DAILY " ,
2017-04-11 17:49:46 +02:00
array ( 'locale' => " en_IE " , 'include_start' => false , 'explicit_infinite' => false ),
2020-02-24 17:39:41 +01:00
" daily " ,
2017-04-11 12:20:20 +02:00
" daily "
),
2019-01-13 11:47:43 +01:00
// with custom_path
'custom_path' => array (
" DTSTART:20170202T000000Z \n RRULE:FREQ=YEARLY;UNTIL=20170205T000000Z " ,
array ( 'locale' => " fr_BE " , " custom_path " => __DIR__ . " /i18n " ),
2020-02-24 17:39:41 +01:00
" chaque année, à partir du 2/02/17, jusqu'au 5/02/17 " ,
" chaque année, à partir du 2017-02-02 00:00:00, jusqu'au 2017-02-05 00:00:00 "
2019-01-13 11:47:43 +01:00
),
'custom_path cached separately' => array (
" DTSTART:20170202T000000Z \n RRULE:FREQ=YEARLY;UNTIL=20170205T000000Z " ,
array ( 'locale' => " fr_BE " ),
" tous les ans, à partir du 2/02/17, jusqu'au 5/02/17 " ,
2020-02-24 17:39:41 +01:00
" tous les ans, à partir du 2017-02-02 00:00:00, jusqu'au 2017-02-05 00:00:00 "
2019-01-13 11:47:43 +01:00
),
array (
" RRULE:FREQ=DAILY;UNTIL=20190405T055959Z " ,
array ( 'locale' => " xx " , " custom_path " => __DIR__ . " /i18n " , " date_formatter " => function ( $date ) { return " X " ; }),
2020-02-24 17:39:41 +01:00
" daily, starting from X, until X " ,
2019-01-13 11:47:43 +01:00
" daily, starting from X, until X "
),
2017-02-02 23:35:09 +01:00
);
}
/**
* @ dataProvider humanReadableStrings
*/
2020-02-24 17:39:41 +01:00
public function testHumanReadable ( $rrule , $options , $withIntl , $withoutIntl , $dtstart = null )
2017-02-02 23:35:09 +01:00
{
2019-01-13 10:29:25 +01:00
if ( $dtstart ) {
$dtstart = new DateTime ( $dtstart );
}
$rrule = new RRule ( $rrule , $dtstart );
2020-02-24 17:39:41 +01:00
$expected = extension_loaded ( 'intl' ) ? $withIntl : $withoutIntl ;
$this -> assertEquals ( $expected , $rrule -> humanReadable ( $options ));
2017-02-02 23:35:09 +01:00
}
2016-03-11 10:02:40 +01:00
}