diff --git a/inc/RRule.php b/inc/RRule.php index 9349c2ec..0c570a56 100644 --- a/inc/RRule.php +++ b/inc/RRule.php @@ -156,8 +156,10 @@ class iCalDate { /** * Set the day of week used for calculation of week starts + * + * @param string $weekstart The day of the week which is the first business day. */ - function SetWeekStart() { + function SetWeekStart($weekstart) { global $ical_weekdays; $this->_wkst = $ical_weekdays[$weekstart]; } @@ -288,6 +290,7 @@ class iCalDate { if ( $matches[2] == 'W' ) $days *= 7; $this->AddDays( $days * $sign ); } + $hh = 0; $mi = 0; $ss = 0; if ( preg_match( '/(\d+)(H)/', $time, $matches ) ) $hh = $matches[1]; if ( preg_match( '/(\d+)(M)/', $time, $matches ) ) $mi = $matches[1]; if ( preg_match( '/(\d+)(S)/', $time, $matches ) ) $ss = $matches[1]; @@ -722,7 +725,7 @@ class RRule { dbg_error_log( "RRule", " new RRule: Start: %s, RRULE: %s", $start->Render(), $this->_rule ); $parts = split(';',$this->_rule); - $this->_part = array(); + $this->_part = array( 'INTERVAL' => 1 ); foreach( $parts AS $k => $v ) { list( $type, $value ) = split( '=', $v, 2); dbg_error_log( "RRule", " Parts of %s split into %s and %s", $v, $type, $value ); @@ -742,15 +745,10 @@ class RRule { if ( !preg_match( '/(YEAR|MONTH|WEEK|DAI)LY/', $this->_part['FREQ']) ) { dbg_error_log( "ERROR", " RRULE Only FREQ=(YEARLY|MONTHLY|WEEKLY|DAILY) are supported at present (%s)", $rrule ); } - if ( ! isset($this->_part['INTERVAL']) ) $this->_part['INTERVAL'] = 1; if ( $this->_part['FREQ'] == "YEARLY" ) { $this->_part['INTERVAL'] *= 12; $this->_part['FREQ'] = "MONTHLY"; } -// if ( $this->_part['FREQ'] == "WEEKLY" ) { -// $this->_part['INTERVAL'] *= 7; -// $this->_part['FREQ'] = "DAILY"; -// } } @@ -820,11 +818,6 @@ class RRule { */ function &GetNext( ) { - if ( $this->_finished ) { - $next = null; - return $next; - } - if ( $this->_current < 0 ) { $next = new iCalDate($this->_first); $this->_current++; @@ -833,14 +826,6 @@ class RRule { $next = new iCalDate($this->_dates[$this->_current]); $this->_current++; -/* - dbg_error_log( "RRule", " GetNext: Continuing: %s, starting from %s, consider %s, (%d'th)", - isset($this->_started) , - (isset($next) ? $next->Render() : "not calculated"), - (isset($this->_dates[$this->_current]) ? $this->_dates[$this->_current]->Render():"not calculated") , - $this->_current ); -*/ - /** * If we have already found some dates we may just be able to return one of those. */ @@ -854,11 +839,16 @@ class RRule { } } + if ( $this->_finished ) { + $next = null; + return $next; + } + $days = array(); if ( isset($this->_part['WKST']) ) $next->SetWeekStart($this->_part['WKST']); if ( $this->_part['FREQ'] == "MONTHLY" ) { dbg_error_log( "RRule", " GetNext: Calculating more dates for MONTHLY rule" ); - $limit = 100; + $limit = 200; do { $limit--; do { @@ -870,7 +860,7 @@ class RRule { $this->_started = true; } } - while ( $limit && ! $next->TestByMonth($this->_part['BYMONTH']) ); + while ( isset($this->_part['BYMONTH']) && $limit > 0 && ! $next->TestByMonth($this->_part['BYMONTH']) ); if ( isset($this->_part['BYDAY']) ) { $days = $next->GetMonthByDay($this->_part['BYDAY']); @@ -893,7 +883,7 @@ class RRule { } else if ( $this->_part['FREQ'] == "WEEKLY" ) { dbg_error_log( "RRule", " GetNext: Calculating more dates for WEEKLY rule" ); - $limit = 100; + $limit = 200; do { $limit--; if ( $this->_started ) { diff --git a/inc/test-RRULE.php b/inc/test-RRULE.php index ea1e5b7b..ee3e947c 100644 --- a/inc/test-RRULE.php +++ b/inc/test-RRULE.php @@ -9,33 +9,70 @@ Testing the RRule Library EOTXT; -$tests = array( - "20061103T073000" => "RRULE:FREQ=DAILY;COUNT=7" - , "20061102T100000" => "RRULE:FREQ=WEEKLY;COUNT=26;INTERVAL=1;BYDAY=TH" - , "20061103T160000" => "RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20071222T235900" - , "20061101T160000" => "RRULE:FREQ=WEEKLY;COUNT=15;INTERVAL=1;BYDAY=MO,WE,FR" - , "20061104T073000" => "RRULE:FREQ=MONTHLY" - , "20061117T073000" => "RRULE:FREQ=MONTHLY;BYDAY=1MO,2WE,3FR,-1SU" - , "20061107T103000" => "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR" - , "20061107T113000" => "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1" - , "20081020T110000" => "RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR" -); +class RRuleTest { + var $dtstart; + var $recur; + var $description; + var $result_description; -foreach( $tests AS $start => $rrule ) { - echo "$start - $rrule\n"; - - $rule = new RRule( new iCalDate($start), $rrule ); - $i = 0; - do { - if ( ($i % 4) == 0 ) echo "\n"; - $date = $rule->GetNext(); - if ( isset($date) ) { - echo " " . $date->Render(); - } + function RRuleTest( $description, $start, $recur, $result_description = null ) { + $this->description = $description; + $this->dtstart = $start; + $this->recur = $recur; + $this->result_description = $result_description; } - while( isset($date) && $i++ < 30 ); - echo "\n\n\n"; + function PHPTest() { + echo "=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=\n"; + echo "$this->dtstart - $this->recur\n"; + echo "$this->description\n"; + + $rule = new RRule( new iCalDate($this->dtstart), $this->recur ); + $i = 0; + do { + if ( ($i % 4) == 0 ) echo "\n"; + $date = $rule->GetNext(); + if ( isset($date) ) { + echo " " . $date->Render(); + } + } + while( isset($date) && $i++ < 30 ); + + echo "\n\n"; + } + + function SQLTest() { + $sql = "SELECT event_instances::timestamp AS event_date FROM event_instances(?,?) LIMIT 30;"; + $qry = new PgQuery($sql, $this->dtstart, $this->recur); + printf( "%s\n", $qry->querystring); + if ( $qry->Exec("test") && $qry->rows > 0 ) { + $i = 0; + while( $row = $qry->Fetch() ) { + if ( ($i++ % 4) == 0 ) echo "\n"; + echo " " . $row->event_date; + } + } + echo "\n\n"; + } } + +$tests = array( + new RRuleTest( "Daily for 7 days", "20061103T073000", "RRULE:FREQ=DAILY;COUNT=7" ) + , new RRuleTest( "Weekly for 26 weeks", "20061102T100000", "RRULE:FREQ=WEEKLY;COUNT=26;INTERVAL=1;BYDAY=TH" ) + , new RRuleTest( "Fortnightly for 28 events", "20061103T160000", "RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20071122T235900" ) + , new RRuleTest( "3/wk for 5 weeks", "20081101T160000", "RRULE:FREQ=WEEKLY;COUNT=15;INTERVAL=1;BYDAY=MO,WE,FR" ) + , new RRuleTest( "Monthly forever", "20061104T073000", "RRULE:FREQ=MONTHLY" ) + , new RRuleTest( "Monthly, on the 1st monday, 2nd wednesday, 3rd friday and last sunday, forever", "20061117T073000", "RRULE:FREQ=MONTHLY;BYDAY=1MO,2WE,3FR,-1SU" ) + , new RRuleTest( "Every working day", "20081020T103000", "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR" ) + , new RRuleTest( "The last working day of each month", "20061107T113000", "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1" ) + , new RRuleTest( "Every working day", "20081020T110000", "RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR" ) +); + +foreach( $tests AS $k => $test ) { + $test->PHPTest(); +// $test->SQLTest(); +} + + exit(0); diff --git a/testing/tests/regression-suite/831-Spec-RRULE-1.result b/testing/tests/regression-suite/831-Spec-RRULE-1.result index be371a03..c0ea5884 100644 --- a/testing/tests/regression-suite/831-Spec-RRULE-1.result +++ b/testing/tests/regression-suite/831-Spec-RRULE-1.result @@ -1,17 +1,20 @@ HTTP/1.1 200 OK Date: Dow, 01 Jan 2000 00:00:00 GMT DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule -Content-Length: 5780 +Content-Length: 6621 Content-Type: text/plain Testing the RRule Library +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061103T073000 - RRULE:FREQ=DAILY;COUNT=7 +Daily for 7 days 2006-11-03 07:30:00 2006-11-04 07:30:00 2006-11-05 07:30:00 2006-11-06 07:30:00 2006-11-07 07:30:00 2006-11-08 07:30:00 2006-11-09 07:30:00 - +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061102T100000 - RRULE:FREQ=WEEKLY;COUNT=26;INTERVAL=1;BYDAY=TH +Weekly for 26 weeks 2006-11-02 10:00:00 2006-11-09 10:00:00 2006-11-16 10:00:00 2006-11-23 10:00:00 2006-11-30 10:00:00 2006-12-07 10:00:00 2006-12-14 10:00:00 2006-12-21 10:00:00 @@ -21,8 +24,9 @@ Testing the RRule Library 2007-03-22 10:00:00 2007-03-29 10:00:00 2007-04-05 10:00:00 2007-04-12 10:00:00 2007-04-19 10:00:00 2007-04-26 10:00:00 - -20061103T160000 - RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20071222T235900 +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= +20061103T160000 - RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20071122T235900 +Fortnightly for 28 events 2006-11-03 16:00:00 2006-11-17 16:00:00 2006-12-01 16:00:00 2006-12-15 16:00:00 2006-12-29 16:00:00 2007-01-12 16:00:00 2007-01-26 16:00:00 2007-02-09 16:00:00 @@ -31,18 +35,20 @@ Testing the RRule Library 2007-06-15 16:00:00 2007-06-29 16:00:00 2007-07-13 16:00:00 2007-07-27 16:00:00 2007-08-10 16:00:00 2007-08-24 16:00:00 2007-09-07 16:00:00 2007-09-21 16:00:00 2007-10-05 16:00:00 2007-10-19 16:00:00 2007-11-02 16:00:00 2007-11-16 16:00:00 - 2007-11-30 16:00:00 2007-12-14 16:00:00 -20061101T160000 - RRULE:FREQ=WEEKLY;COUNT=15;INTERVAL=1;BYDAY=MO,WE,FR - - 2006-11-01 16:00:00 2006-11-03 16:00:00 2006-11-06 16:00:00 2006-11-08 16:00:00 - 2006-11-10 16:00:00 2006-11-13 16:00:00 2006-11-15 16:00:00 2006-11-17 16:00:00 - 2006-11-20 16:00:00 2006-11-22 16:00:00 2006-11-24 16:00:00 2006-11-27 16:00:00 - 2006-11-29 16:00:00 2006-12-01 16:00:00 2006-12-04 16:00:00 +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= +20081101T160000 - RRULE:FREQ=WEEKLY;COUNT=15;INTERVAL=1;BYDAY=MO,WE,FR +3/wk for 5 weeks + 2008-11-03 16:00:00 2008-11-05 16:00:00 2008-11-07 16:00:00 2008-11-10 16:00:00 + 2008-11-12 16:00:00 2008-11-14 16:00:00 2008-11-17 16:00:00 2008-11-19 16:00:00 + 2008-11-21 16:00:00 2008-11-24 16:00:00 2008-11-26 16:00:00 2008-11-28 16:00:00 + 2008-12-01 16:00:00 2008-12-03 16:00:00 2008-12-05 16:00:00 +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061104T073000 - RRULE:FREQ=MONTHLY +Monthly forever 2006-11-04 07:30:00 2006-12-04 07:30:00 2007-01-04 07:30:00 2007-02-04 07:30:00 2007-03-04 07:30:00 2007-04-04 07:30:00 2007-05-04 07:30:00 2007-06-04 07:30:00 @@ -53,8 +59,9 @@ Testing the RRule Library 2008-11-04 07:30:00 2008-12-04 07:30:00 2009-01-04 07:30:00 2009-02-04 07:30:00 2009-03-04 07:30:00 2009-04-04 07:30:00 2009-05-04 07:30:00 - +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061117T073000 - RRULE:FREQ=MONTHLY;BYDAY=1MO,2WE,3FR,-1SU +Monthly, on the 1st monday, 2nd wednesday, 3rd friday and last sunday, forever 2006-11-17 07:30:00 2006-11-26 07:30:00 2006-12-04 07:30:00 2006-12-13 07:30:00 2006-12-15 07:30:00 2006-12-31 07:30:00 2007-01-01 07:30:00 2007-01-10 07:30:00 @@ -65,20 +72,22 @@ Testing the RRule Library 2007-05-18 07:30:00 2007-05-27 07:30:00 2007-06-04 07:30:00 2007-06-13 07:30:00 2007-06-15 07:30:00 2007-06-24 07:30:00 2007-07-02 07:30:00 +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= +20081020T103000 - RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR +Every working day -20061107T103000 - RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR - - 2006-11-07 10:30:00 2006-11-08 10:30:00 2006-11-09 10:30:00 2006-11-10 10:30:00 - 2006-11-13 10:30:00 2006-11-14 10:30:00 2006-11-15 10:30:00 2006-11-16 10:30:00 - 2006-11-17 10:30:00 2006-11-20 10:30:00 2006-11-21 10:30:00 2006-11-22 10:30:00 - 2006-11-23 10:30:00 2006-11-24 10:30:00 2006-11-27 10:30:00 2006-11-28 10:30:00 - 2006-11-29 10:30:00 2006-11-30 10:30:00 2006-12-01 10:30:00 2006-12-04 10:30:00 - 2006-12-05 10:30:00 2006-12-06 10:30:00 2006-12-07 10:30:00 2006-12-08 10:30:00 - 2006-12-11 10:30:00 2006-12-12 10:30:00 2006-12-13 10:30:00 2006-12-14 10:30:00 - 2006-12-15 10:30:00 2006-12-18 10:30:00 2006-12-19 10:30:00 - + 2008-10-20 10:30:00 2008-10-21 10:30:00 2008-10-22 10:30:00 2008-10-23 10:30:00 + 2008-10-24 10:30:00 2008-10-27 10:30:00 2008-10-28 10:30:00 2008-10-29 10:30:00 + 2008-10-30 10:30:00 2008-10-31 10:30:00 2008-11-03 10:30:00 2008-11-04 10:30:00 + 2008-11-05 10:30:00 2008-11-06 10:30:00 2008-11-07 10:30:00 2008-11-10 10:30:00 + 2008-11-11 10:30:00 2008-11-12 10:30:00 2008-11-13 10:30:00 2008-11-14 10:30:00 + 2008-11-17 10:30:00 2008-11-18 10:30:00 2008-11-19 10:30:00 2008-11-20 10:30:00 + 2008-11-21 10:30:00 2008-11-24 10:30:00 2008-11-25 10:30:00 2008-11-26 10:30:00 + 2008-11-27 10:30:00 2008-11-28 10:30:00 2008-12-01 10:30:00 +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061107T113000 - RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1 +The last working day of each month 2006-11-30 11:30:00 2006-12-29 11:30:00 2007-01-31 11:30:00 2007-02-28 11:30:00 2007-03-30 11:30:00 2007-04-30 11:30:00 2007-05-31 11:30:00 2007-06-29 11:30:00 @@ -89,16 +98,16 @@ Testing the RRule Library 2008-11-28 11:30:00 2008-12-31 11:30:00 2009-01-30 11:30:00 2009-02-27 11:30:00 2009-03-31 11:30:00 2009-04-30 11:30:00 2009-05-29 11:30:00 - +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20081020T110000 - RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR +Every working day - 2008-10-21 11:00:00 2008-10-22 11:00:00 2008-10-23 11:00:00 2008-10-24 11:00:00 - 2008-10-27 11:00:00 2008-10-28 11:00:00 2008-10-29 11:00:00 2008-10-30 11:00:00 - 2008-10-31 11:00:00 2008-11-03 11:00:00 2008-11-04 11:00:00 2008-11-05 11:00:00 - 2008-11-06 11:00:00 2008-11-07 11:00:00 2008-11-10 11:00:00 2008-11-11 11:00:00 - 2008-11-12 11:00:00 2008-11-13 11:00:00 2008-11-14 11:00:00 2008-11-17 11:00:00 - 2008-11-18 11:00:00 2008-11-19 11:00:00 2008-11-20 11:00:00 2008-11-21 11:00:00 - 2008-11-24 11:00:00 2008-11-25 11:00:00 2008-11-26 11:00:00 2008-11-27 11:00:00 - 2008-11-28 11:00:00 2008-12-01 11:00:00 2008-12-02 11:00:00 - + 2008-10-20 11:00:00 2008-10-21 11:00:00 2008-10-22 11:00:00 2008-10-23 11:00:00 + 2008-10-24 11:00:00 2008-10-27 11:00:00 2008-10-28 11:00:00 2008-10-29 11:00:00 + 2008-10-30 11:00:00 2008-10-31 11:00:00 2008-11-03 11:00:00 2008-11-04 11:00:00 + 2008-11-05 11:00:00 2008-11-06 11:00:00 2008-11-07 11:00:00 2008-11-10 11:00:00 + 2008-11-11 11:00:00 2008-11-12 11:00:00 2008-11-13 11:00:00 2008-11-14 11:00:00 + 2008-11-17 11:00:00 2008-11-18 11:00:00 2008-11-19 11:00:00 2008-11-20 11:00:00 + 2008-11-21 11:00:00 2008-11-24 11:00:00 2008-11-25 11:00:00 2008-11-26 11:00:00 + 2008-11-27 11:00:00 2008-11-28 11:00:00 2008-12-01 11:00:00