1*a1a3b679SAndreas Boehler<?php 2*a1a3b679SAndreas Boehler 3*a1a3b679SAndreas Boehlernamespace Sabre\VObject\Recur; 4*a1a3b679SAndreas Boehler 5*a1a3b679SAndreas Boehleruse DateTime; 6*a1a3b679SAndreas Boehleruse DateTimeZone; 7*a1a3b679SAndreas Boehler 8*a1a3b679SAndreas Boehlerclass RRuleIteratorTest extends \PHPUnit_Framework_TestCase { 9*a1a3b679SAndreas Boehler 10*a1a3b679SAndreas Boehler function testHourly() { 11*a1a3b679SAndreas Boehler 12*a1a3b679SAndreas Boehler $this->parse( 13*a1a3b679SAndreas Boehler 'FREQ=HOURLY;INTERVAL=3;COUNT=12', 14*a1a3b679SAndreas Boehler '2011-10-07 12:00:00', 15*a1a3b679SAndreas Boehler array( 16*a1a3b679SAndreas Boehler '2011-10-07 12:00:00', 17*a1a3b679SAndreas Boehler '2011-10-07 15:00:00', 18*a1a3b679SAndreas Boehler '2011-10-07 18:00:00', 19*a1a3b679SAndreas Boehler '2011-10-07 21:00:00', 20*a1a3b679SAndreas Boehler '2011-10-08 00:00:00', 21*a1a3b679SAndreas Boehler '2011-10-08 03:00:00', 22*a1a3b679SAndreas Boehler '2011-10-08 06:00:00', 23*a1a3b679SAndreas Boehler '2011-10-08 09:00:00', 24*a1a3b679SAndreas Boehler '2011-10-08 12:00:00', 25*a1a3b679SAndreas Boehler '2011-10-08 15:00:00', 26*a1a3b679SAndreas Boehler '2011-10-08 18:00:00', 27*a1a3b679SAndreas Boehler '2011-10-08 21:00:00', 28*a1a3b679SAndreas Boehler ) 29*a1a3b679SAndreas Boehler ); 30*a1a3b679SAndreas Boehler 31*a1a3b679SAndreas Boehler } 32*a1a3b679SAndreas Boehler 33*a1a3b679SAndreas Boehler function testDaily() { 34*a1a3b679SAndreas Boehler 35*a1a3b679SAndreas Boehler $this->parse( 36*a1a3b679SAndreas Boehler 'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z', 37*a1a3b679SAndreas Boehler '2011-10-07', 38*a1a3b679SAndreas Boehler array( 39*a1a3b679SAndreas Boehler '2011-10-07 00:00:00', 40*a1a3b679SAndreas Boehler '2011-10-10 00:00:00', 41*a1a3b679SAndreas Boehler '2011-10-13 00:00:00', 42*a1a3b679SAndreas Boehler '2011-10-16 00:00:00', 43*a1a3b679SAndreas Boehler '2011-10-19 00:00:00', 44*a1a3b679SAndreas Boehler '2011-10-22 00:00:00', 45*a1a3b679SAndreas Boehler '2011-10-25 00:00:00', 46*a1a3b679SAndreas Boehler ) 47*a1a3b679SAndreas Boehler ); 48*a1a3b679SAndreas Boehler 49*a1a3b679SAndreas Boehler } 50*a1a3b679SAndreas Boehler 51*a1a3b679SAndreas Boehler function testDailyByDayByHour() { 52*a1a3b679SAndreas Boehler 53*a1a3b679SAndreas Boehler $this->parse( 54*a1a3b679SAndreas Boehler 'FREQ=DAILY;BYDAY=SA,SU;BYHOUR=6,7', 55*a1a3b679SAndreas Boehler '2011-10-08 06:00:00', 56*a1a3b679SAndreas Boehler array( 57*a1a3b679SAndreas Boehler '2011-10-08 06:00:00', 58*a1a3b679SAndreas Boehler '2011-10-08 07:00:00', 59*a1a3b679SAndreas Boehler '2011-10-09 06:00:00', 60*a1a3b679SAndreas Boehler '2011-10-09 07:00:00', 61*a1a3b679SAndreas Boehler '2011-10-15 06:00:00', 62*a1a3b679SAndreas Boehler '2011-10-15 07:00:00', 63*a1a3b679SAndreas Boehler '2011-10-16 06:00:00', 64*a1a3b679SAndreas Boehler '2011-10-16 07:00:00', 65*a1a3b679SAndreas Boehler '2011-10-22 06:00:00', 66*a1a3b679SAndreas Boehler '2011-10-22 07:00:00', 67*a1a3b679SAndreas Boehler '2011-10-23 06:00:00', 68*a1a3b679SAndreas Boehler '2011-10-23 07:00:00', 69*a1a3b679SAndreas Boehler ) 70*a1a3b679SAndreas Boehler ); 71*a1a3b679SAndreas Boehler 72*a1a3b679SAndreas Boehler } 73*a1a3b679SAndreas Boehler 74*a1a3b679SAndreas Boehler function testDailyByHour() { 75*a1a3b679SAndreas Boehler 76*a1a3b679SAndreas Boehler $this->parse( 77*a1a3b679SAndreas Boehler 'FREQ=DAILY;INTERVAL=2;BYHOUR=10,11,12,13,14,15', 78*a1a3b679SAndreas Boehler '2012-10-11 12:00:00', 79*a1a3b679SAndreas Boehler array( 80*a1a3b679SAndreas Boehler '2012-10-11 12:00:00', 81*a1a3b679SAndreas Boehler '2012-10-11 13:00:00', 82*a1a3b679SAndreas Boehler '2012-10-11 14:00:00', 83*a1a3b679SAndreas Boehler '2012-10-11 15:00:00', 84*a1a3b679SAndreas Boehler '2012-10-13 10:00:00', 85*a1a3b679SAndreas Boehler '2012-10-13 11:00:00', 86*a1a3b679SAndreas Boehler '2012-10-13 12:00:00', 87*a1a3b679SAndreas Boehler '2012-10-13 13:00:00', 88*a1a3b679SAndreas Boehler '2012-10-13 14:00:00', 89*a1a3b679SAndreas Boehler '2012-10-13 15:00:00', 90*a1a3b679SAndreas Boehler '2012-10-15 10:00:00', 91*a1a3b679SAndreas Boehler '2012-10-15 11:00:00', 92*a1a3b679SAndreas Boehler ) 93*a1a3b679SAndreas Boehler ); 94*a1a3b679SAndreas Boehler 95*a1a3b679SAndreas Boehler } 96*a1a3b679SAndreas Boehler 97*a1a3b679SAndreas Boehler function testDailyByDay() { 98*a1a3b679SAndreas Boehler 99*a1a3b679SAndreas Boehler $this->parse( 100*a1a3b679SAndreas Boehler 'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR', 101*a1a3b679SAndreas Boehler '2011-10-07 12:00:00', 102*a1a3b679SAndreas Boehler array( 103*a1a3b679SAndreas Boehler '2011-10-07 12:00:00', 104*a1a3b679SAndreas Boehler '2011-10-11 12:00:00', 105*a1a3b679SAndreas Boehler '2011-10-19 12:00:00', 106*a1a3b679SAndreas Boehler '2011-10-21 12:00:00', 107*a1a3b679SAndreas Boehler '2011-10-25 12:00:00', 108*a1a3b679SAndreas Boehler '2011-11-02 12:00:00', 109*a1a3b679SAndreas Boehler '2011-11-04 12:00:00', 110*a1a3b679SAndreas Boehler '2011-11-08 12:00:00', 111*a1a3b679SAndreas Boehler '2011-11-16 12:00:00', 112*a1a3b679SAndreas Boehler '2011-11-18 12:00:00', 113*a1a3b679SAndreas Boehler '2011-11-22 12:00:00', 114*a1a3b679SAndreas Boehler '2011-11-30 12:00:00', 115*a1a3b679SAndreas Boehler ) 116*a1a3b679SAndreas Boehler ); 117*a1a3b679SAndreas Boehler 118*a1a3b679SAndreas Boehler } 119*a1a3b679SAndreas Boehler 120*a1a3b679SAndreas Boehler function testDailyCount() { 121*a1a3b679SAndreas Boehler 122*a1a3b679SAndreas Boehler $this->parse( 123*a1a3b679SAndreas Boehler 'FREQ=DAILY;COUNT=5', 124*a1a3b679SAndreas Boehler '2014-08-01 18:03:00', 125*a1a3b679SAndreas Boehler array( 126*a1a3b679SAndreas Boehler '2014-08-01 18:03:00', 127*a1a3b679SAndreas Boehler '2014-08-02 18:03:00', 128*a1a3b679SAndreas Boehler '2014-08-03 18:03:00', 129*a1a3b679SAndreas Boehler '2014-08-04 18:03:00', 130*a1a3b679SAndreas Boehler '2014-08-05 18:03:00', 131*a1a3b679SAndreas Boehler ) 132*a1a3b679SAndreas Boehler ); 133*a1a3b679SAndreas Boehler 134*a1a3b679SAndreas Boehler } 135*a1a3b679SAndreas Boehler 136*a1a3b679SAndreas Boehler function testDailyByMonth() { 137*a1a3b679SAndreas Boehler 138*a1a3b679SAndreas Boehler $this->parse( 139*a1a3b679SAndreas Boehler 'FREQ=DAILY;BYMONTH=9,10;BYDAY=SU', 140*a1a3b679SAndreas Boehler '2007-10-04 16:00:00', 141*a1a3b679SAndreas Boehler array( 142*a1a3b679SAndreas Boehler "2013-09-29 16:00:00", 143*a1a3b679SAndreas Boehler "2013-10-06 16:00:00", 144*a1a3b679SAndreas Boehler "2013-10-13 16:00:00", 145*a1a3b679SAndreas Boehler "2013-10-20 16:00:00", 146*a1a3b679SAndreas Boehler "2013-10-27 16:00:00", 147*a1a3b679SAndreas Boehler "2014-09-07 16:00:00" 148*a1a3b679SAndreas Boehler ), 149*a1a3b679SAndreas Boehler '2013-09-28' 150*a1a3b679SAndreas Boehler ); 151*a1a3b679SAndreas Boehler 152*a1a3b679SAndreas Boehler } 153*a1a3b679SAndreas Boehler 154*a1a3b679SAndreas Boehler function testWeekly() { 155*a1a3b679SAndreas Boehler 156*a1a3b679SAndreas Boehler $this->parse( 157*a1a3b679SAndreas Boehler 'FREQ=WEEKLY;INTERVAL=2;COUNT=10', 158*a1a3b679SAndreas Boehler '2011-10-07 00:00:00', 159*a1a3b679SAndreas Boehler array( 160*a1a3b679SAndreas Boehler '2011-10-07 00:00:00', 161*a1a3b679SAndreas Boehler '2011-10-21 00:00:00', 162*a1a3b679SAndreas Boehler '2011-11-04 00:00:00', 163*a1a3b679SAndreas Boehler '2011-11-18 00:00:00', 164*a1a3b679SAndreas Boehler '2011-12-02 00:00:00', 165*a1a3b679SAndreas Boehler '2011-12-16 00:00:00', 166*a1a3b679SAndreas Boehler '2011-12-30 00:00:00', 167*a1a3b679SAndreas Boehler '2012-01-13 00:00:00', 168*a1a3b679SAndreas Boehler '2012-01-27 00:00:00', 169*a1a3b679SAndreas Boehler '2012-02-10 00:00:00', 170*a1a3b679SAndreas Boehler ) 171*a1a3b679SAndreas Boehler ); 172*a1a3b679SAndreas Boehler 173*a1a3b679SAndreas Boehler } 174*a1a3b679SAndreas Boehler 175*a1a3b679SAndreas Boehler function testWeeklyByDay() { 176*a1a3b679SAndreas Boehler 177*a1a3b679SAndreas Boehler $this->parse( 178*a1a3b679SAndreas Boehler 'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=MO;WKST=SA', 179*a1a3b679SAndreas Boehler '2014-08-01 00:00:00', 180*a1a3b679SAndreas Boehler array( 181*a1a3b679SAndreas Boehler '2014-08-01 00:00:00', 182*a1a3b679SAndreas Boehler '2014-08-04 00:00:00', 183*a1a3b679SAndreas Boehler '2014-08-11 00:00:00', 184*a1a3b679SAndreas Boehler '2014-08-18 00:00:00', 185*a1a3b679SAndreas Boehler ) 186*a1a3b679SAndreas Boehler ); 187*a1a3b679SAndreas Boehler 188*a1a3b679SAndreas Boehler } 189*a1a3b679SAndreas Boehler 190*a1a3b679SAndreas Boehler function testWeeklyByDay2() { 191*a1a3b679SAndreas Boehler 192*a1a3b679SAndreas Boehler $this->parse( 193*a1a3b679SAndreas Boehler 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU', 194*a1a3b679SAndreas Boehler '2011-10-07 00:00:00', 195*a1a3b679SAndreas Boehler array( 196*a1a3b679SAndreas Boehler '2011-10-07 00:00:00', 197*a1a3b679SAndreas Boehler '2011-10-18 00:00:00', 198*a1a3b679SAndreas Boehler '2011-10-19 00:00:00', 199*a1a3b679SAndreas Boehler '2011-10-21 00:00:00', 200*a1a3b679SAndreas Boehler '2011-11-01 00:00:00', 201*a1a3b679SAndreas Boehler '2011-11-02 00:00:00', 202*a1a3b679SAndreas Boehler '2011-11-04 00:00:00', 203*a1a3b679SAndreas Boehler '2011-11-15 00:00:00', 204*a1a3b679SAndreas Boehler '2011-11-16 00:00:00', 205*a1a3b679SAndreas Boehler '2011-11-18 00:00:00', 206*a1a3b679SAndreas Boehler '2011-11-29 00:00:00', 207*a1a3b679SAndreas Boehler '2011-11-30 00:00:00', 208*a1a3b679SAndreas Boehler ) 209*a1a3b679SAndreas Boehler ); 210*a1a3b679SAndreas Boehler 211*a1a3b679SAndreas Boehler } 212*a1a3b679SAndreas Boehler 213*a1a3b679SAndreas Boehler function testWeeklyByDayByHour() { 214*a1a3b679SAndreas Boehler 215*a1a3b679SAndreas Boehler $this->parse( 216*a1a3b679SAndreas Boehler 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=MO;BYHOUR=8,9,10', 217*a1a3b679SAndreas Boehler '2011-10-07 08:00:00', 218*a1a3b679SAndreas Boehler array( 219*a1a3b679SAndreas Boehler '2011-10-07 08:00:00', 220*a1a3b679SAndreas Boehler '2011-10-07 09:00:00', 221*a1a3b679SAndreas Boehler '2011-10-07 10:00:00', 222*a1a3b679SAndreas Boehler '2011-10-18 08:00:00', 223*a1a3b679SAndreas Boehler '2011-10-18 09:00:00', 224*a1a3b679SAndreas Boehler '2011-10-18 10:00:00', 225*a1a3b679SAndreas Boehler '2011-10-19 08:00:00', 226*a1a3b679SAndreas Boehler '2011-10-19 09:00:00', 227*a1a3b679SAndreas Boehler '2011-10-19 10:00:00', 228*a1a3b679SAndreas Boehler '2011-10-21 08:00:00', 229*a1a3b679SAndreas Boehler '2011-10-21 09:00:00', 230*a1a3b679SAndreas Boehler '2011-10-21 10:00:00', 231*a1a3b679SAndreas Boehler '2011-11-01 08:00:00', 232*a1a3b679SAndreas Boehler '2011-11-01 09:00:00', 233*a1a3b679SAndreas Boehler '2011-11-01 10:00:00', 234*a1a3b679SAndreas Boehler ) 235*a1a3b679SAndreas Boehler ); 236*a1a3b679SAndreas Boehler 237*a1a3b679SAndreas Boehler } 238*a1a3b679SAndreas Boehler 239*a1a3b679SAndreas Boehler function testWeeklyByDaySpecificHour() { 240*a1a3b679SAndreas Boehler 241*a1a3b679SAndreas Boehler $this->parse( 242*a1a3b679SAndreas Boehler 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU', 243*a1a3b679SAndreas Boehler '2011-10-07 18:00:00', 244*a1a3b679SAndreas Boehler array( 245*a1a3b679SAndreas Boehler '2011-10-07 18:00:00', 246*a1a3b679SAndreas Boehler '2011-10-18 18:00:00', 247*a1a3b679SAndreas Boehler '2011-10-19 18:00:00', 248*a1a3b679SAndreas Boehler '2011-10-21 18:00:00', 249*a1a3b679SAndreas Boehler '2011-11-01 18:00:00', 250*a1a3b679SAndreas Boehler '2011-11-02 18:00:00', 251*a1a3b679SAndreas Boehler '2011-11-04 18:00:00', 252*a1a3b679SAndreas Boehler '2011-11-15 18:00:00', 253*a1a3b679SAndreas Boehler '2011-11-16 18:00:00', 254*a1a3b679SAndreas Boehler '2011-11-18 18:00:00', 255*a1a3b679SAndreas Boehler '2011-11-29 18:00:00', 256*a1a3b679SAndreas Boehler '2011-11-30 18:00:00', 257*a1a3b679SAndreas Boehler ) 258*a1a3b679SAndreas Boehler ); 259*a1a3b679SAndreas Boehler 260*a1a3b679SAndreas Boehler } 261*a1a3b679SAndreas Boehler 262*a1a3b679SAndreas Boehler function testMonthly() { 263*a1a3b679SAndreas Boehler 264*a1a3b679SAndreas Boehler $this->parse( 265*a1a3b679SAndreas Boehler 'FREQ=MONTHLY;INTERVAL=3;COUNT=5', 266*a1a3b679SAndreas Boehler '2011-12-05 00:00:00', 267*a1a3b679SAndreas Boehler array( 268*a1a3b679SAndreas Boehler '2011-12-05 00:00:00', 269*a1a3b679SAndreas Boehler '2012-03-05 00:00:00', 270*a1a3b679SAndreas Boehler '2012-06-05 00:00:00', 271*a1a3b679SAndreas Boehler '2012-09-05 00:00:00', 272*a1a3b679SAndreas Boehler '2012-12-05 00:00:00', 273*a1a3b679SAndreas Boehler ) 274*a1a3b679SAndreas Boehler ); 275*a1a3b679SAndreas Boehler 276*a1a3b679SAndreas Boehler } 277*a1a3b679SAndreas Boehler 278*a1a3b679SAndreas Boehler function testMonlthyEndOfMonth() { 279*a1a3b679SAndreas Boehler 280*a1a3b679SAndreas Boehler $this->parse( 281*a1a3b679SAndreas Boehler 'FREQ=MONTHLY;INTERVAL=2;COUNT=12', 282*a1a3b679SAndreas Boehler '2011-12-31 00:00:00', 283*a1a3b679SAndreas Boehler array( 284*a1a3b679SAndreas Boehler '2011-12-31 00:00:00', 285*a1a3b679SAndreas Boehler '2012-08-31 00:00:00', 286*a1a3b679SAndreas Boehler '2012-10-31 00:00:00', 287*a1a3b679SAndreas Boehler '2012-12-31 00:00:00', 288*a1a3b679SAndreas Boehler '2013-08-31 00:00:00', 289*a1a3b679SAndreas Boehler '2013-10-31 00:00:00', 290*a1a3b679SAndreas Boehler '2013-12-31 00:00:00', 291*a1a3b679SAndreas Boehler '2014-08-31 00:00:00', 292*a1a3b679SAndreas Boehler '2014-10-31 00:00:00', 293*a1a3b679SAndreas Boehler '2014-12-31 00:00:00', 294*a1a3b679SAndreas Boehler '2015-08-31 00:00:00', 295*a1a3b679SAndreas Boehler '2015-10-31 00:00:00', 296*a1a3b679SAndreas Boehler ) 297*a1a3b679SAndreas Boehler ); 298*a1a3b679SAndreas Boehler 299*a1a3b679SAndreas Boehler } 300*a1a3b679SAndreas Boehler 301*a1a3b679SAndreas Boehler function testMonthlyByMonthDay() { 302*a1a3b679SAndreas Boehler 303*a1a3b679SAndreas Boehler $this->parse( 304*a1a3b679SAndreas Boehler 'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7', 305*a1a3b679SAndreas Boehler '2011-01-01 00:00:00', 306*a1a3b679SAndreas Boehler array( 307*a1a3b679SAndreas Boehler '2011-01-01 00:00:00', 308*a1a3b679SAndreas Boehler '2011-01-25 00:00:00', 309*a1a3b679SAndreas Boehler '2011-01-31 00:00:00', 310*a1a3b679SAndreas Boehler '2011-06-01 00:00:00', 311*a1a3b679SAndreas Boehler '2011-06-24 00:00:00', 312*a1a3b679SAndreas Boehler '2011-11-01 00:00:00', 313*a1a3b679SAndreas Boehler '2011-11-24 00:00:00', 314*a1a3b679SAndreas Boehler '2012-04-01 00:00:00', 315*a1a3b679SAndreas Boehler '2012-04-24 00:00:00', 316*a1a3b679SAndreas Boehler ) 317*a1a3b679SAndreas Boehler ); 318*a1a3b679SAndreas Boehler 319*a1a3b679SAndreas Boehler } 320*a1a3b679SAndreas Boehler 321*a1a3b679SAndreas Boehler function testMonthlyByDay() { 322*a1a3b679SAndreas Boehler 323*a1a3b679SAndreas Boehler $this->parse( 324*a1a3b679SAndreas Boehler 'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH', 325*a1a3b679SAndreas Boehler '2011-01-03 00:00:00', 326*a1a3b679SAndreas Boehler array( 327*a1a3b679SAndreas Boehler '2011-01-03 00:00:00', 328*a1a3b679SAndreas Boehler '2011-01-05 00:00:00', 329*a1a3b679SAndreas Boehler '2011-01-10 00:00:00', 330*a1a3b679SAndreas Boehler '2011-01-17 00:00:00', 331*a1a3b679SAndreas Boehler '2011-01-18 00:00:00', 332*a1a3b679SAndreas Boehler '2011-01-20 00:00:00', 333*a1a3b679SAndreas Boehler '2011-01-24 00:00:00', 334*a1a3b679SAndreas Boehler '2011-01-31 00:00:00', 335*a1a3b679SAndreas Boehler '2011-03-02 00:00:00', 336*a1a3b679SAndreas Boehler '2011-03-07 00:00:00', 337*a1a3b679SAndreas Boehler '2011-03-14 00:00:00', 338*a1a3b679SAndreas Boehler '2011-03-17 00:00:00', 339*a1a3b679SAndreas Boehler '2011-03-21 00:00:00', 340*a1a3b679SAndreas Boehler '2011-03-22 00:00:00', 341*a1a3b679SAndreas Boehler '2011-03-28 00:00:00', 342*a1a3b679SAndreas Boehler '2011-05-02 00:00:00', 343*a1a3b679SAndreas Boehler ) 344*a1a3b679SAndreas Boehler ); 345*a1a3b679SAndreas Boehler 346*a1a3b679SAndreas Boehler } 347*a1a3b679SAndreas Boehler 348*a1a3b679SAndreas Boehler function testMonthlyByDayByMonthDay() { 349*a1a3b679SAndreas Boehler 350*a1a3b679SAndreas Boehler $this->parse( 351*a1a3b679SAndreas Boehler 'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1', 352*a1a3b679SAndreas Boehler '2011-08-01 00:00:00', 353*a1a3b679SAndreas Boehler array( 354*a1a3b679SAndreas Boehler '2011-08-01 00:00:00', 355*a1a3b679SAndreas Boehler '2012-10-01 00:00:00', 356*a1a3b679SAndreas Boehler '2013-04-01 00:00:00', 357*a1a3b679SAndreas Boehler '2013-07-01 00:00:00', 358*a1a3b679SAndreas Boehler '2014-09-01 00:00:00', 359*a1a3b679SAndreas Boehler '2014-12-01 00:00:00', 360*a1a3b679SAndreas Boehler '2015-06-01 00:00:00', 361*a1a3b679SAndreas Boehler '2016-02-01 00:00:00', 362*a1a3b679SAndreas Boehler '2016-08-01 00:00:00', 363*a1a3b679SAndreas Boehler '2017-05-01 00:00:00', 364*a1a3b679SAndreas Boehler ) 365*a1a3b679SAndreas Boehler ); 366*a1a3b679SAndreas Boehler 367*a1a3b679SAndreas Boehler } 368*a1a3b679SAndreas Boehler 369*a1a3b679SAndreas Boehler function testMonthlyByDayBySetPos() { 370*a1a3b679SAndreas Boehler 371*a1a3b679SAndreas Boehler $this->parse( 372*a1a3b679SAndreas Boehler 'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1', 373*a1a3b679SAndreas Boehler '2011-01-03 00:00:00', 374*a1a3b679SAndreas Boehler array( 375*a1a3b679SAndreas Boehler '2011-01-03 00:00:00', 376*a1a3b679SAndreas Boehler '2011-01-31 00:00:00', 377*a1a3b679SAndreas Boehler '2011-02-01 00:00:00', 378*a1a3b679SAndreas Boehler '2011-02-28 00:00:00', 379*a1a3b679SAndreas Boehler '2011-03-01 00:00:00', 380*a1a3b679SAndreas Boehler '2011-03-31 00:00:00', 381*a1a3b679SAndreas Boehler '2011-04-01 00:00:00', 382*a1a3b679SAndreas Boehler '2011-04-29 00:00:00', 383*a1a3b679SAndreas Boehler '2011-05-02 00:00:00', 384*a1a3b679SAndreas Boehler '2011-05-31 00:00:00', 385*a1a3b679SAndreas Boehler ) 386*a1a3b679SAndreas Boehler ); 387*a1a3b679SAndreas Boehler 388*a1a3b679SAndreas Boehler } 389*a1a3b679SAndreas Boehler 390*a1a3b679SAndreas Boehler function testYearly() { 391*a1a3b679SAndreas Boehler 392*a1a3b679SAndreas Boehler $this->parse( 393*a1a3b679SAndreas Boehler 'FREQ=YEARLY;COUNT=10;INTERVAL=3', 394*a1a3b679SAndreas Boehler '2011-01-01 00:00:00', 395*a1a3b679SAndreas Boehler array( 396*a1a3b679SAndreas Boehler '2011-01-01 00:00:00', 397*a1a3b679SAndreas Boehler '2014-01-01 00:00:00', 398*a1a3b679SAndreas Boehler '2017-01-01 00:00:00', 399*a1a3b679SAndreas Boehler '2020-01-01 00:00:00', 400*a1a3b679SAndreas Boehler '2023-01-01 00:00:00', 401*a1a3b679SAndreas Boehler '2026-01-01 00:00:00', 402*a1a3b679SAndreas Boehler '2029-01-01 00:00:00', 403*a1a3b679SAndreas Boehler '2032-01-01 00:00:00', 404*a1a3b679SAndreas Boehler '2035-01-01 00:00:00', 405*a1a3b679SAndreas Boehler '2038-01-01 00:00:00', 406*a1a3b679SAndreas Boehler ) 407*a1a3b679SAndreas Boehler ); 408*a1a3b679SAndreas Boehler } 409*a1a3b679SAndreas Boehler 410*a1a3b679SAndreas Boehler function testYearlyLeapYear() { 411*a1a3b679SAndreas Boehler 412*a1a3b679SAndreas Boehler $this->parse( 413*a1a3b679SAndreas Boehler 'FREQ=YEARLY;COUNT=3', 414*a1a3b679SAndreas Boehler '2012-02-29 00:00:00', 415*a1a3b679SAndreas Boehler array( 416*a1a3b679SAndreas Boehler '2012-02-29 00:00:00', 417*a1a3b679SAndreas Boehler '2016-02-29 00:00:00', 418*a1a3b679SAndreas Boehler '2020-02-29 00:00:00', 419*a1a3b679SAndreas Boehler ) 420*a1a3b679SAndreas Boehler ); 421*a1a3b679SAndreas Boehler } 422*a1a3b679SAndreas Boehler 423*a1a3b679SAndreas Boehler function testYearlyByMonth() { 424*a1a3b679SAndreas Boehler 425*a1a3b679SAndreas Boehler $this->parse( 426*a1a3b679SAndreas Boehler 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10', 427*a1a3b679SAndreas Boehler '2011-04-07 00:00:00', 428*a1a3b679SAndreas Boehler array( 429*a1a3b679SAndreas Boehler '2011-04-07 00:00:00', 430*a1a3b679SAndreas Boehler '2011-10-07 00:00:00', 431*a1a3b679SAndreas Boehler '2015-04-07 00:00:00', 432*a1a3b679SAndreas Boehler '2015-10-07 00:00:00', 433*a1a3b679SAndreas Boehler '2019-04-07 00:00:00', 434*a1a3b679SAndreas Boehler '2019-10-07 00:00:00', 435*a1a3b679SAndreas Boehler '2023-04-07 00:00:00', 436*a1a3b679SAndreas Boehler '2023-10-07 00:00:00', 437*a1a3b679SAndreas Boehler ) 438*a1a3b679SAndreas Boehler ); 439*a1a3b679SAndreas Boehler 440*a1a3b679SAndreas Boehler } 441*a1a3b679SAndreas Boehler 442*a1a3b679SAndreas Boehler function testYearlyByMonthByDay() { 443*a1a3b679SAndreas Boehler 444*a1a3b679SAndreas Boehler $this->parse( 445*a1a3b679SAndreas Boehler 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU', 446*a1a3b679SAndreas Boehler '2011-04-04 00:00:00', 447*a1a3b679SAndreas Boehler array( 448*a1a3b679SAndreas Boehler '2011-04-04 00:00:00', 449*a1a3b679SAndreas Boehler '2011-04-24 00:00:00', 450*a1a3b679SAndreas Boehler '2011-10-03 00:00:00', 451*a1a3b679SAndreas Boehler '2011-10-30 00:00:00', 452*a1a3b679SAndreas Boehler '2016-04-04 00:00:00', 453*a1a3b679SAndreas Boehler '2016-04-24 00:00:00', 454*a1a3b679SAndreas Boehler '2016-10-03 00:00:00', 455*a1a3b679SAndreas Boehler '2016-10-30 00:00:00', 456*a1a3b679SAndreas Boehler ) 457*a1a3b679SAndreas Boehler ); 458*a1a3b679SAndreas Boehler 459*a1a3b679SAndreas Boehler } 460*a1a3b679SAndreas Boehler 461*a1a3b679SAndreas Boehler function testFastForward() { 462*a1a3b679SAndreas Boehler 463*a1a3b679SAndreas Boehler // The idea is that we're fast-forwarding too far in the future, so 464*a1a3b679SAndreas Boehler // there will be no results left. 465*a1a3b679SAndreas Boehler $this->parse( 466*a1a3b679SAndreas Boehler 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU', 467*a1a3b679SAndreas Boehler '2011-04-04 00:00:00', 468*a1a3b679SAndreas Boehler array(), 469*a1a3b679SAndreas Boehler '2020-05-05 00:00:00' 470*a1a3b679SAndreas Boehler ); 471*a1a3b679SAndreas Boehler 472*a1a3b679SAndreas Boehler } 473*a1a3b679SAndreas Boehler 474*a1a3b679SAndreas Boehler /** 475*a1a3b679SAndreas Boehler * The bug that was in the 476*a1a3b679SAndreas Boehler * system before would fail on the 5th tuesday of the month, if the 5th 477*a1a3b679SAndreas Boehler * tuesday did not exist. 478*a1a3b679SAndreas Boehler * 479*a1a3b679SAndreas Boehler * A pretty slow test. Had to be marked as 'medium' for phpunit to not die 480*a1a3b679SAndreas Boehler * after 1 second. Would be good to optimize later. 481*a1a3b679SAndreas Boehler * 482*a1a3b679SAndreas Boehler * @medium 483*a1a3b679SAndreas Boehler */ 484*a1a3b679SAndreas Boehler function testFifthTuesdayProblem() { 485*a1a3b679SAndreas Boehler 486*a1a3b679SAndreas Boehler $this->parse( 487*a1a3b679SAndreas Boehler 'FREQ=MONTHLY;INTERVAL=1;UNTIL=20071030T035959Z;BYDAY=5TU', 488*a1a3b679SAndreas Boehler '2007-10-04 14:46:42', 489*a1a3b679SAndreas Boehler array( 490*a1a3b679SAndreas Boehler "2007-10-04 14:46:42", 491*a1a3b679SAndreas Boehler ) 492*a1a3b679SAndreas Boehler ); 493*a1a3b679SAndreas Boehler 494*a1a3b679SAndreas Boehler } 495*a1a3b679SAndreas Boehler 496*a1a3b679SAndreas Boehler /** 497*a1a3b679SAndreas Boehler * This bug came from a Fruux customer. This would result in a never-ending 498*a1a3b679SAndreas Boehler * request. 499*a1a3b679SAndreas Boehler */ 500*a1a3b679SAndreas Boehler function testFastFowardTooFar() { 501*a1a3b679SAndreas Boehler 502*a1a3b679SAndreas Boehler $this->parse( 503*a1a3b679SAndreas Boehler 'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1', 504*a1a3b679SAndreas Boehler '2009-04-20 18:00:00', 505*a1a3b679SAndreas Boehler array( 506*a1a3b679SAndreas Boehler '2009-04-20 18:00:00', 507*a1a3b679SAndreas Boehler '2009-04-27 18:00:00', 508*a1a3b679SAndreas Boehler '2009-05-04 18:00:00', 509*a1a3b679SAndreas Boehler '2009-05-11 18:00:00', 510*a1a3b679SAndreas Boehler '2009-05-18 18:00:00', 511*a1a3b679SAndreas Boehler '2009-05-25 18:00:00', 512*a1a3b679SAndreas Boehler '2009-06-01 18:00:00', 513*a1a3b679SAndreas Boehler '2009-06-08 18:00:00', 514*a1a3b679SAndreas Boehler '2009-06-15 18:00:00', 515*a1a3b679SAndreas Boehler '2009-06-22 18:00:00', 516*a1a3b679SAndreas Boehler '2009-06-29 18:00:00', 517*a1a3b679SAndreas Boehler ) 518*a1a3b679SAndreas Boehler ); 519*a1a3b679SAndreas Boehler 520*a1a3b679SAndreas Boehler } 521*a1a3b679SAndreas Boehler 522*a1a3b679SAndreas Boehler /** 523*a1a3b679SAndreas Boehler * This also at one point caused an infinite loop. We're keeping the test. 524*a1a3b679SAndreas Boehler */ 525*a1a3b679SAndreas Boehler function testYearlyByMonthLoop() { 526*a1a3b679SAndreas Boehler 527*a1a3b679SAndreas Boehler $this->parse( 528*a1a3b679SAndreas Boehler 'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA', 529*a1a3b679SAndreas Boehler '2012-01-01 15:45:00', 530*a1a3b679SAndreas Boehler array( 531*a1a3b679SAndreas Boehler '2012-02-01 15:45:00', 532*a1a3b679SAndreas Boehler ), 533*a1a3b679SAndreas Boehler '2012-01-29 23:00:00' 534*a1a3b679SAndreas Boehler ); 535*a1a3b679SAndreas Boehler 536*a1a3b679SAndreas Boehler 537*a1a3b679SAndreas Boehler } 538*a1a3b679SAndreas Boehler 539*a1a3b679SAndreas Boehler /** 540*a1a3b679SAndreas Boehler * Something, somewhere produced an ics with an interval set to 0. Because 541*a1a3b679SAndreas Boehler * this means we increase the current day (or week, month) by 0, this also 542*a1a3b679SAndreas Boehler * results in an infinite loop. 543*a1a3b679SAndreas Boehler * 544*a1a3b679SAndreas Boehler * @expectedException InvalidArgumentException 545*a1a3b679SAndreas Boehler */ 546*a1a3b679SAndreas Boehler function testZeroInterval() { 547*a1a3b679SAndreas Boehler 548*a1a3b679SAndreas Boehler $this->parse( 549*a1a3b679SAndreas Boehler 'FREQ=YEARLY;INTERVAL=0', 550*a1a3b679SAndreas Boehler '2012-08-24 14:57:00', 551*a1a3b679SAndreas Boehler array(), 552*a1a3b679SAndreas Boehler '2013-01-01 23:00:00' 553*a1a3b679SAndreas Boehler ); 554*a1a3b679SAndreas Boehler 555*a1a3b679SAndreas Boehler } 556*a1a3b679SAndreas Boehler 557*a1a3b679SAndreas Boehler /** 558*a1a3b679SAndreas Boehler * @expectedException InvalidArgumentException 559*a1a3b679SAndreas Boehler */ 560*a1a3b679SAndreas Boehler function testInvalidFreq() { 561*a1a3b679SAndreas Boehler 562*a1a3b679SAndreas Boehler $this->parse( 563*a1a3b679SAndreas Boehler 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z', 564*a1a3b679SAndreas Boehler '2011-10-07', 565*a1a3b679SAndreas Boehler array() 566*a1a3b679SAndreas Boehler ); 567*a1a3b679SAndreas Boehler 568*a1a3b679SAndreas Boehler } 569*a1a3b679SAndreas Boehler 570*a1a3b679SAndreas Boehler /** 571*a1a3b679SAndreas Boehler * @expectedException InvalidArgumentException 572*a1a3b679SAndreas Boehler */ 573*a1a3b679SAndreas Boehler function testByDayBadOffset() { 574*a1a3b679SAndreas Boehler 575*a1a3b679SAndreas Boehler $this->parse( 576*a1a3b679SAndreas Boehler 'FREQ=WEEKLY;INTERVAL=1;COUNT=4;BYDAY=0MO;WKST=SA', 577*a1a3b679SAndreas Boehler '2014-08-01 00:00:00', 578*a1a3b679SAndreas Boehler array() 579*a1a3b679SAndreas Boehler ); 580*a1a3b679SAndreas Boehler 581*a1a3b679SAndreas Boehler } 582*a1a3b679SAndreas Boehler 583*a1a3b679SAndreas Boehler function testUntilBeginHAsTimezone() { 584*a1a3b679SAndreas Boehler 585*a1a3b679SAndreas Boehler $this->parse( 586*a1a3b679SAndreas Boehler 'FREQ=WEEKLY;UNTIL=20131118T183000', 587*a1a3b679SAndreas Boehler '2013-09-23 18:30:00', 588*a1a3b679SAndreas Boehler array( 589*a1a3b679SAndreas Boehler '2013-09-23 18:30:00', 590*a1a3b679SAndreas Boehler '2013-09-30 18:30:00', 591*a1a3b679SAndreas Boehler '2013-10-07 18:30:00', 592*a1a3b679SAndreas Boehler '2013-10-14 18:30:00', 593*a1a3b679SAndreas Boehler '2013-10-21 18:30:00', 594*a1a3b679SAndreas Boehler '2013-10-28 18:30:00', 595*a1a3b679SAndreas Boehler '2013-11-04 18:30:00', 596*a1a3b679SAndreas Boehler '2013-11-11 18:30:00', 597*a1a3b679SAndreas Boehler '2013-11-18 18:30:00', 598*a1a3b679SAndreas Boehler ), 599*a1a3b679SAndreas Boehler null, 600*a1a3b679SAndreas Boehler 'America/New_York' 601*a1a3b679SAndreas Boehler ); 602*a1a3b679SAndreas Boehler 603*a1a3b679SAndreas Boehler } 604*a1a3b679SAndreas Boehler 605*a1a3b679SAndreas Boehler function testUntilBeforeDtStart() { 606*a1a3b679SAndreas Boehler 607*a1a3b679SAndreas Boehler $this->parse( 608*a1a3b679SAndreas Boehler 'FREQ=DAILY;UNTIL=20140101T000000Z', 609*a1a3b679SAndreas Boehler '2014-08-02 00:15:00', 610*a1a3b679SAndreas Boehler array( 611*a1a3b679SAndreas Boehler '2014-08-02 00:15:00', 612*a1a3b679SAndreas Boehler ) 613*a1a3b679SAndreas Boehler ); 614*a1a3b679SAndreas Boehler 615*a1a3b679SAndreas Boehler } 616*a1a3b679SAndreas Boehler 617*a1a3b679SAndreas Boehler function testIgnoredStuff() { 618*a1a3b679SAndreas Boehler 619*a1a3b679SAndreas Boehler $this->parse( 620*a1a3b679SAndreas Boehler 'FREQ=DAILY;BYSECOND=1;BYMINUTE=1;BYYEARDAY=1;BYWEEKNO=1;COUNT=2', 621*a1a3b679SAndreas Boehler '2014-08-02 00:15:00', 622*a1a3b679SAndreas Boehler array( 623*a1a3b679SAndreas Boehler '2014-08-02 00:15:00', 624*a1a3b679SAndreas Boehler '2014-08-03 00:15:00', 625*a1a3b679SAndreas Boehler ) 626*a1a3b679SAndreas Boehler ); 627*a1a3b679SAndreas Boehler 628*a1a3b679SAndreas Boehler } 629*a1a3b679SAndreas Boehler 630*a1a3b679SAndreas Boehler function testMinusFifthThursday() { 631*a1a3b679SAndreas Boehler 632*a1a3b679SAndreas Boehler $this->parse( 633*a1a3b679SAndreas Boehler 'FREQ=MONTHLY;BYDAY=-4TH,-5TH;COUNT=4', 634*a1a3b679SAndreas Boehler '2015-01-01 00:15:00', 635*a1a3b679SAndreas Boehler array( 636*a1a3b679SAndreas Boehler '2015-01-01 00:15:00', 637*a1a3b679SAndreas Boehler '2015-01-08 00:15:00', 638*a1a3b679SAndreas Boehler '2015-02-05 00:15:00', 639*a1a3b679SAndreas Boehler '2015-03-05 00:15:00' 640*a1a3b679SAndreas Boehler ) 641*a1a3b679SAndreas Boehler ); 642*a1a3b679SAndreas Boehler 643*a1a3b679SAndreas Boehler } 644*a1a3b679SAndreas Boehler 645*a1a3b679SAndreas Boehler /** 646*a1a3b679SAndreas Boehler * @expectedException InvalidArgumentException 647*a1a3b679SAndreas Boehler */ 648*a1a3b679SAndreas Boehler function testUnsupportedPart() { 649*a1a3b679SAndreas Boehler 650*a1a3b679SAndreas Boehler $this->parse( 651*a1a3b679SAndreas Boehler 'FREQ=DAILY;BYWODAN=1', 652*a1a3b679SAndreas Boehler '2014-08-02 00:15:00', 653*a1a3b679SAndreas Boehler array() 654*a1a3b679SAndreas Boehler ); 655*a1a3b679SAndreas Boehler 656*a1a3b679SAndreas Boehler } 657*a1a3b679SAndreas Boehler 658*a1a3b679SAndreas Boehler function testIteratorFunctions() { 659*a1a3b679SAndreas Boehler 660*a1a3b679SAndreas Boehler $parser = new RRuleIterator('FREQ=DAILY', new DateTime('2014-08-02 00:00:13')); 661*a1a3b679SAndreas Boehler $parser->next(); 662*a1a3b679SAndreas Boehler $this->assertEquals( 663*a1a3b679SAndreas Boehler new DateTime('2014-08-03 00:00:13'), 664*a1a3b679SAndreas Boehler $parser->current() 665*a1a3b679SAndreas Boehler ); 666*a1a3b679SAndreas Boehler $this->assertEquals( 667*a1a3b679SAndreas Boehler 1, 668*a1a3b679SAndreas Boehler $parser->key() 669*a1a3b679SAndreas Boehler ); 670*a1a3b679SAndreas Boehler 671*a1a3b679SAndreas Boehler $parser->rewind(); 672*a1a3b679SAndreas Boehler 673*a1a3b679SAndreas Boehler $this->assertEquals( 674*a1a3b679SAndreas Boehler new DateTime('2014-08-02 00:00:13'), 675*a1a3b679SAndreas Boehler $parser->current() 676*a1a3b679SAndreas Boehler ); 677*a1a3b679SAndreas Boehler $this->assertEquals( 678*a1a3b679SAndreas Boehler 0, 679*a1a3b679SAndreas Boehler $parser->key() 680*a1a3b679SAndreas Boehler ); 681*a1a3b679SAndreas Boehler 682*a1a3b679SAndreas Boehler } 683*a1a3b679SAndreas Boehler 684*a1a3b679SAndreas Boehler function parse($rule, $start, $expected, $fastForward = null, $tz = 'UTC') { 685*a1a3b679SAndreas Boehler 686*a1a3b679SAndreas Boehler $dt = new DateTime($start, new DateTimeZone($tz)); 687*a1a3b679SAndreas Boehler $parser = new RRuleIterator($rule, $dt); 688*a1a3b679SAndreas Boehler 689*a1a3b679SAndreas Boehler if ($fastForward) { 690*a1a3b679SAndreas Boehler $parser->fastForward(new DateTime($fastForward)); 691*a1a3b679SAndreas Boehler } 692*a1a3b679SAndreas Boehler 693*a1a3b679SAndreas Boehler $result = array(); 694*a1a3b679SAndreas Boehler while($parser->valid()) { 695*a1a3b679SAndreas Boehler 696*a1a3b679SAndreas Boehler $item = $parser->current(); 697*a1a3b679SAndreas Boehler $result[] = $item->format('Y-m-d H:i:s'); 698*a1a3b679SAndreas Boehler 699*a1a3b679SAndreas Boehler if ($parser->isInfinite() && count($result) >= count($expected)) { 700*a1a3b679SAndreas Boehler break; 701*a1a3b679SAndreas Boehler } 702*a1a3b679SAndreas Boehler $parser->next(); 703*a1a3b679SAndreas Boehler 704*a1a3b679SAndreas Boehler } 705*a1a3b679SAndreas Boehler 706*a1a3b679SAndreas Boehler $this->assertEquals( 707*a1a3b679SAndreas Boehler $expected, 708*a1a3b679SAndreas Boehler $result 709*a1a3b679SAndreas Boehler ); 710*a1a3b679SAndreas Boehler 711*a1a3b679SAndreas Boehler } 712*a1a3b679SAndreas Boehler 713*a1a3b679SAndreas Boehler} 714