From e4f48ddc1af7f757e6e8bf9048d48a31fd119662 Mon Sep 17 00:00:00 2001 From: Andrew Ruthven Date: Wed, 11 Aug 2021 22:36:38 +1200 Subject: [PATCH] For RRULE BYMONTHDAY skip expansions where the new day is not the day we expect. This fixes one of the issues raised in #248. --- inc/RRule.php | 8 +- testing/test-RRULE-v2.php | 3 + .../regression-suite/0831-Spec-RRULE-1.result | 402 +++++++++++++++++- 3 files changed, 399 insertions(+), 14 deletions(-) diff --git a/inc/RRule.php b/inc/RRule.php index 14c7bfbe..b5a36c39 100644 --- a/inc/RRule.php +++ b/inc/RRule.php @@ -879,8 +879,12 @@ class RepeatRule { foreach( $instances AS $k => $instance ) { foreach( $this->bymonthday AS $k => $monthday ) { $expanded = $this->date_mask( clone($instance), null, null, $monthday, null, null, null); - if ( DEBUG_RRULE ) printf( "Expanded BYMONTHDAY $monthday into date %s from %s\n", $expanded->format('c'), $instance->format('c') ); - $this->current_set[] = $expanded; + if ($monthday == -1 || $expanded->format('d') == $monthday) { + if ( DEBUG_RRULE ) printf( "Expanded BYMONTHDAY $monthday into date %s from %s\n", $expanded->format('c'), $instance->format('c') ); + $this->current_set[] = $expanded; + } else { + if ( DEBUG_RRULE ) printf( "Expanded BYMONTHDAY $monthday into date %s from %s, which is not the same day of month, skipping.\n", $expanded->format('c'), $instance->format('c') ); + } } } } diff --git a/testing/test-RRULE-v2.php b/testing/test-RRULE-v2.php index 5f864061..d8ab2a76 100755 --- a/testing/test-RRULE-v2.php +++ b/testing/test-RRULE-v2.php @@ -91,6 +91,7 @@ $tests = array( , new RRuleTest( "Time zone 4", "20000404T010000", "FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;COUNT=15" ) , new RRuleTest( "Six Working Days", "20110905", "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;COUNT=6" ) , new RRuleTest( "Six Working Days", "20110905", "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;COUNT=6" ) + , new RRuleTest( "31st of each month", "20110831", "RRULE:FREQ=MONTHLY;BYMONTHDAY=31;COUNT=12" ) ); foreach( $tests AS $k => $test ) { @@ -101,6 +102,8 @@ foreach( $tests AS $k => $test ) { $sql_result = $test->SQLTest(); if ( $php_result == $sql_result ) { printf( 'PHP & SQL results are identical (-: P: %6.4lf & S: %6.4lf'."\n", $test->PHP_time, $test->SQL_time); + echo "PHP Result:\n$php_result\n\n"; + echo "SQL Result:\n$sql_result\n\n"; } else { printf( 'PHP & SQL results differ :-( P: %6.4lf & S: %6.4lf'."\n", $test->PHP_time, $test->SQL_time); diff --git a/testing/tests/regression-suite/0831-Spec-RRULE-1.result b/testing/tests/regression-suite/0831-Spec-RRULE-1.result index 9c1cbded..88a121de 100644 --- a/testing/tests/regression-suite/0831-Spec-RRULE-1.result +++ b/testing/tests/regression-suite/0831-Spec-RRULE-1.result @@ -1,60 +1,278 @@ -HTTP/1.1 200 OK -Date: Dow, 01 Jan 2000 00:00:00 GMT -DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule -DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy -Content-Length: 7623 -Content-Type: text/plain; charset=UTF-8 - -#!/usr/bin/php Testing the RRule v2 Library =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061103T073000 - RRULE:FREQ=DAILY;COUNT=7 Daily for 7 days PHP & SQL results are identical (-: +PHP Result: + + 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 + +SQL Result: + + 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 PHP & SQL results are identical (-: +PHP Result: + + 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 + 2006-12-28 10:00:00 2007-01-04 10:00:00 2007-01-11 10:00:00 2007-01-18 10:00:00 + 2007-01-25 10:00:00 2007-02-01 10:00:00 2007-02-08 10:00:00 2007-02-15 10:00:00 + 2007-02-22 10:00:00 2007-03-01 10:00:00 2007-03-08 10:00:00 2007-03-15 10:00:00 + 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 + +SQL Result: + + 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 + 2006-12-28 10:00:00 2007-01-04 10:00:00 2007-01-11 10:00:00 2007-01-18 10:00:00 + 2007-01-25 10:00:00 2007-02-01 10:00:00 2007-02-08 10:00:00 2007-02-15 10:00:00 + 2007-02-22 10:00:00 2007-03-01 10:00:00 2007-03-08 10:00:00 2007-03-15 10:00:00 + 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;COUNT=4 Fortnightly for 4 events PHP & SQL results are identical (-: +PHP Result: + + 2006-11-03 16:00:00 2006-11-17 16:00:00 2006-12-01 16:00:00 2006-12-15 16:00:00 + +SQL Result: + + 2006-11-03 16:00:00 2006-11-17 16:00:00 2006-12-01 16:00:00 2006-12-15 16:00:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061103T160000 - RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20071122T235900 Fortnightly for 28 events PHP & SQL results are identical (-: +PHP Result: + + 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 + 2007-02-23 16:00:00 2007-03-09 16:00:00 2007-03-23 16:00:00 2007-04-06 16:00:00 + 2007-04-20 16:00:00 2007-05-04 16:00:00 2007-05-18 16:00:00 2007-06-01 16:00:00 + 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 + +SQL Result: + + 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 + 2007-02-23 16:00:00 2007-03-09 16:00:00 2007-03-23 16:00:00 2007-04-06 16:00:00 + 2007-04-20 16:00:00 2007-05-04 16:00:00 2007-05-18 16:00:00 2007-06-01 16:00:00 + 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 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20081101T160000 - RRULE:FREQ=WEEKLY;COUNT=15;INTERVAL=1;BYDAY=MO,WE,FR 3/wk for 5 weeks PHP & SQL results are identical (-: +PHP Result: + + 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 + +SQL Result: + + 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 PHP & SQL results are identical (-: +PHP Result: + + 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 + 2007-07-04 07:30:00 2007-08-04 07:30:00 2007-09-04 07:30:00 2007-10-04 07:30:00 + 2007-11-04 07:30:00 2007-12-04 07:30:00 2008-01-04 07:30:00 2008-02-04 07:30:00 + 2008-03-04 07:30:00 2008-04-04 07:30:00 2008-05-04 07:30:00 2008-06-04 07:30:00 + 2008-07-04 07:30:00 2008-08-04 07:30:00 2008-09-04 07:30:00 2008-10-04 07:30:00 + 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 + +SQL Result: + + 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 + 2007-07-04 07:30:00 2007-08-04 07:30:00 2007-09-04 07:30:00 2007-10-04 07:30:00 + 2007-11-04 07:30:00 2007-12-04 07:30:00 2008-01-04 07:30:00 2008-02-04 07:30:00 + 2008-03-04 07:30:00 2008-04-04 07:30:00 2008-05-04 07:30:00 2008-06-04 07:30:00 + 2008-07-04 07:30:00 2008-08-04 07:30:00 2008-09-04 07:30:00 2008-10-04 07:30:00 + 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 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061117T073000 - RRULE:FREQ=MONTHLY;BYDAY=1MO,2WE,3FR,-1SU Monthly, on the 1st monday, 2nd wednesday, 3rd friday and last sunday, forever PHP & SQL results are identical (-: +PHP Result: + + 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 + 2007-01-19 07:30:00 2007-01-28 07:30:00 2007-02-05 07:30:00 2007-02-14 07:30:00 + 2007-02-16 07:30:00 2007-02-25 07:30:00 2007-03-05 07:30:00 2007-03-14 07:30:00 + 2007-03-16 07:30:00 2007-03-25 07:30:00 2007-04-02 07:30:00 2007-04-11 07:30:00 + 2007-04-20 07:30:00 2007-04-29 07:30:00 2007-05-07 07:30:00 2007-05-09 07:30:00 + 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 + +SQL Result: + + 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 + 2007-01-19 07:30:00 2007-01-28 07:30:00 2007-02-05 07:30:00 2007-02-14 07:30:00 + 2007-02-16 07:30:00 2007-02-25 07:30:00 2007-03-05 07:30:00 2007-03-14 07:30:00 + 2007-03-16 07:30:00 2007-03-25 07:30:00 2007-04-02 07:30:00 2007-04-11 07:30:00 + 2007-04-20 07:30:00 2007-04-29 07:30:00 2007-05-07 07:30:00 2007-05-09 07:30:00 + 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 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061107T113000 - RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;UNTIL=20070101T000000 The working days of each month PHP & SQL results are identical (-: +PHP Result: + + 2006-11-07 11:30:00 2006-11-08 11:30:00 2006-11-09 11:30:00 2006-11-10 11:30:00 + 2006-11-13 11:30:00 2006-11-14 11:30:00 2006-11-15 11:30:00 2006-11-16 11:30:00 + 2006-11-17 11:30:00 2006-11-20 11:30:00 2006-11-21 11:30:00 2006-11-22 11:30:00 + 2006-11-23 11:30:00 2006-11-24 11:30:00 2006-11-27 11:30:00 2006-11-28 11:30:00 + 2006-11-29 11:30:00 2006-11-30 11:30:00 2006-12-01 11:30:00 2006-12-04 11:30:00 + 2006-12-05 11:30:00 2006-12-06 11:30:00 2006-12-07 11:30:00 2006-12-08 11:30:00 + 2006-12-11 11:30:00 2006-12-12 11:30:00 2006-12-13 11:30:00 2006-12-14 11:30:00 + 2006-12-15 11:30:00 2006-12-18 11:30:00 + +SQL Result: + + 2006-11-07 11:30:00 2006-11-08 11:30:00 2006-11-09 11:30:00 2006-11-10 11:30:00 + 2006-11-13 11:30:00 2006-11-14 11:30:00 2006-11-15 11:30:00 2006-11-16 11:30:00 + 2006-11-17 11:30:00 2006-11-20 11:30:00 2006-11-21 11:30:00 2006-11-22 11:30:00 + 2006-11-23 11:30:00 2006-11-24 11:30:00 2006-11-27 11:30:00 2006-11-28 11:30:00 + 2006-11-29 11:30:00 2006-11-30 11:30:00 2006-12-01 11:30:00 2006-12-04 11:30:00 + 2006-12-05 11:30:00 2006-12-06 11:30:00 2006-12-07 11:30:00 2006-12-08 11:30:00 + 2006-12-11 11:30:00 2006-12-12 11:30:00 2006-12-13 11:30:00 2006-12-14 11:30:00 + 2006-12-15 11:30:00 2006-12-18 11:30:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20061107T113000 - RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1;COUNT=30 The last working day of each month PHP & SQL results are identical (-: +PHP Result: + + 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 + 2007-07-31 11:30:00 2007-08-31 11:30:00 2007-09-28 11:30:00 2007-10-31 11:30:00 + 2007-11-30 11:30:00 2007-12-31 11:30:00 2008-01-31 11:30:00 2008-02-29 11:30:00 + 2008-03-31 11:30:00 2008-04-30 11:30:00 2008-05-30 11:30:00 2008-06-30 11:30:00 + 2008-07-31 11:30:00 2008-08-29 11:30:00 2008-09-30 11:30:00 2008-10-31 11:30:00 + 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 + +SQL Result: + + 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 + 2007-07-31 11:30:00 2007-08-31 11:30:00 2007-09-28 11:30:00 2007-10-31 11:30:00 + 2007-11-30 11:30:00 2007-12-31 11:30:00 2008-01-31 11:30:00 2008-02-29 11:30:00 + 2008-03-31 11:30:00 2008-04-30 11:30:00 2008-05-30 11:30:00 2008-06-30 11:30:00 + 2008-07-31 11:30:00 2008-08-29 11:30:00 2008-09-30 11:30:00 2008-10-31 11:30:00 + 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 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20081020T103000 - RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;COUNT=30 Every working day PHP & SQL results are identical (-: +PHP Result: + + 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 + +SQL Result: + + 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 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20081020T110000 - RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;COUNT=30 Every working day PHP & SQL results are identical (-: +PHP Result: + + 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 + +SQL Result: + + 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 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20110831 - RRULE:FREQ=MONTHLY;BYMONTHDAY=-1 The last day of each month PHP & SQL results are identical (-: +PHP Result: + + 2011-08-31 00:00:00 2011-09-30 00:00:00 2011-10-31 00:00:00 2011-11-30 00:00:00 + 2011-12-31 00:00:00 2012-01-31 00:00:00 2012-02-29 00:00:00 2012-03-31 00:00:00 + 2012-04-30 00:00:00 2012-05-31 00:00:00 2012-06-30 00:00:00 2012-07-31 00:00:00 + 2012-08-31 00:00:00 2012-09-30 00:00:00 2012-10-31 00:00:00 2012-11-30 00:00:00 + 2012-12-31 00:00:00 2013-01-31 00:00:00 2013-02-28 00:00:00 2013-03-31 00:00:00 + 2013-04-30 00:00:00 2013-05-31 00:00:00 2013-06-30 00:00:00 2013-07-31 00:00:00 + 2013-08-31 00:00:00 2013-09-30 00:00:00 2013-10-31 00:00:00 2013-11-30 00:00:00 + 2013-12-31 00:00:00 2014-01-31 00:00:00 + +SQL Result: + + 2011-08-31 00:00:00 2011-09-30 00:00:00 2011-10-31 00:00:00 2011-11-30 00:00:00 + 2011-12-31 00:00:00 2012-01-31 00:00:00 2012-02-29 00:00:00 2012-03-31 00:00:00 + 2012-04-30 00:00:00 2012-05-31 00:00:00 2012-06-30 00:00:00 2012-07-31 00:00:00 + 2012-08-31 00:00:00 2012-09-30 00:00:00 2012-10-31 00:00:00 2012-11-30 00:00:00 + 2012-12-31 00:00:00 2013-01-31 00:00:00 2013-02-28 00:00:00 2013-03-31 00:00:00 + 2013-04-30 00:00:00 2013-05-31 00:00:00 2013-06-30 00:00:00 2013-07-31 00:00:00 + 2013-08-31 00:00:00 2013-09-30 00:00:00 2013-10-31 00:00:00 2013-11-30 00:00:00 + 2013-12-31 00:00:00 2014-01-31 00:00:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20081001T133000 - RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU,2WE,3TH,4FR;BYMONTH=3,6,9,10,12 1st Tuesday, 2nd Wednesday, 3rd Thursday & 4th Friday, every March, June, September, October and December (SQL is wrong) @@ -85,18 +303,84 @@ SQL Result: 20081017T084500 - RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=TU,FR;COUNT=30 Every tuesday and friday PHP & SQL results are identical (-: +PHP Result: + + 2008-10-17 08:45:00 2008-10-21 08:45:00 2008-10-24 08:45:00 2008-10-28 08:45:00 + 2008-10-31 08:45:00 2008-11-04 08:45:00 2008-11-07 08:45:00 2008-11-11 08:45:00 + 2008-11-14 08:45:00 2008-11-18 08:45:00 2008-11-21 08:45:00 2008-11-25 08:45:00 + 2008-11-28 08:45:00 2008-12-02 08:45:00 2008-12-05 08:45:00 2008-12-09 08:45:00 + 2008-12-12 08:45:00 2008-12-16 08:45:00 2008-12-19 08:45:00 2008-12-23 08:45:00 + 2008-12-26 08:45:00 2008-12-30 08:45:00 2009-01-02 08:45:00 2009-01-06 08:45:00 + 2009-01-09 08:45:00 2009-01-13 08:45:00 2009-01-16 08:45:00 2009-01-20 08:45:00 + 2009-01-23 08:45:00 2009-01-27 08:45:00 + +SQL Result: + + 2008-10-17 08:45:00 2008-10-21 08:45:00 2008-10-24 08:45:00 2008-10-28 08:45:00 + 2008-10-31 08:45:00 2008-11-04 08:45:00 2008-11-07 08:45:00 2008-11-11 08:45:00 + 2008-11-14 08:45:00 2008-11-18 08:45:00 2008-11-21 08:45:00 2008-11-25 08:45:00 + 2008-11-28 08:45:00 2008-12-02 08:45:00 2008-12-05 08:45:00 2008-12-09 08:45:00 + 2008-12-12 08:45:00 2008-12-16 08:45:00 2008-12-19 08:45:00 2008-12-23 08:45:00 + 2008-12-26 08:45:00 2008-12-30 08:45:00 2009-01-02 08:45:00 2009-01-06 08:45:00 + 2009-01-09 08:45:00 2009-01-13 08:45:00 2009-01-16 08:45:00 2009-01-20 08:45:00 + 2009-01-23 08:45:00 2009-01-27 08:45:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20081017T084500 - RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,FR;COUNT=30 Every tuesday and friday PHP & SQL results are identical (-: +PHP Result: + + 2008-10-17 08:45:00 2008-10-21 08:45:00 2008-10-24 08:45:00 2008-10-28 08:45:00 + 2008-10-31 08:45:00 2008-11-04 08:45:00 2008-11-07 08:45:00 2008-11-11 08:45:00 + 2008-11-14 08:45:00 2008-11-18 08:45:00 2008-11-21 08:45:00 2008-11-25 08:45:00 + 2008-11-28 08:45:00 2008-12-02 08:45:00 2008-12-05 08:45:00 2008-12-09 08:45:00 + 2008-12-12 08:45:00 2008-12-16 08:45:00 2008-12-19 08:45:00 2008-12-23 08:45:00 + 2008-12-26 08:45:00 2008-12-30 08:45:00 2009-01-02 08:45:00 2009-01-06 08:45:00 + 2009-01-09 08:45:00 2009-01-13 08:45:00 2009-01-16 08:45:00 2009-01-20 08:45:00 + 2009-01-23 08:45:00 2009-01-27 08:45:00 + +SQL Result: + + 2008-10-17 08:45:00 2008-10-21 08:45:00 2008-10-24 08:45:00 2008-10-28 08:45:00 + 2008-10-31 08:45:00 2008-11-04 08:45:00 2008-11-07 08:45:00 2008-11-11 08:45:00 + 2008-11-14 08:45:00 2008-11-18 08:45:00 2008-11-21 08:45:00 2008-11-25 08:45:00 + 2008-11-28 08:45:00 2008-12-02 08:45:00 2008-12-05 08:45:00 2008-12-09 08:45:00 + 2008-12-12 08:45:00 2008-12-16 08:45:00 2008-12-19 08:45:00 2008-12-23 08:45:00 + 2008-12-26 08:45:00 2008-12-30 08:45:00 2009-01-02 08:45:00 2009-01-06 08:45:00 + 2009-01-09 08:45:00 2009-01-13 08:45:00 2009-01-16 08:45:00 2009-01-20 08:45:00 + 2009-01-23 08:45:00 2009-01-27 08:45:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20081017T084500 - RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=TU,FR;COUNT=30 Every tuesday and friday PHP & SQL results are identical (-: +PHP Result: + + 2008-10-17 08:45:00 2008-10-21 08:45:00 2008-10-24 08:45:00 2008-10-28 08:45:00 + 2008-10-31 08:45:00 2008-11-04 08:45:00 2008-11-07 08:45:00 2008-11-11 08:45:00 + 2008-11-14 08:45:00 2008-11-18 08:45:00 2008-11-21 08:45:00 2008-11-25 08:45:00 + 2008-11-28 08:45:00 2008-12-02 08:45:00 2008-12-05 08:45:00 2008-12-09 08:45:00 + 2008-12-12 08:45:00 2008-12-16 08:45:00 2008-12-19 08:45:00 2008-12-23 08:45:00 + 2008-12-26 08:45:00 2008-12-30 08:45:00 2009-01-02 08:45:00 2009-01-06 08:45:00 + 2009-01-09 08:45:00 2009-01-13 08:45:00 2009-01-16 08:45:00 2009-01-20 08:45:00 + 2009-01-23 08:45:00 2009-01-27 08:45:00 + +SQL Result: + + 2008-10-17 08:45:00 2008-10-21 08:45:00 2008-10-24 08:45:00 2008-10-28 08:45:00 + 2008-10-31 08:45:00 2008-11-04 08:45:00 2008-11-07 08:45:00 2008-11-11 08:45:00 + 2008-11-14 08:45:00 2008-11-18 08:45:00 2008-11-21 08:45:00 2008-11-25 08:45:00 + 2008-11-28 08:45:00 2008-12-02 08:45:00 2008-12-05 08:45:00 2008-12-09 08:45:00 + 2008-12-12 08:45:00 2008-12-16 08:45:00 2008-12-19 08:45:00 2008-12-23 08:45:00 + 2008-12-26 08:45:00 2008-12-30 08:45:00 2009-01-02 08:45:00 2009-01-06 08:45:00 + 2009-01-09 08:45:00 2009-01-13 08:45:00 2009-01-16 08:45:00 2009-01-20 08:45:00 + 2009-01-23 08:45:00 2009-01-27 08:45:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 19700315T030000 - FREQ=YEARLY;INTERVAL=1;BYDAY=3SU;BYMONTH=3 Time zone 1 -PHP & SQL results differ :-( +PHP & SQL results are identical (-: PHP Result: 1970-03-15 03:00:00 1971-03-21 03:00:00 1972-03-19 03:00:00 1973-03-18 03:00:00 @@ -115,27 +399,121 @@ SQL Result: 1978-03-19 03:00:00 1979-03-18 03:00:00 1980-03-16 03:00:00 1981-03-15 03:00:00 1982-03-21 03:00:00 1983-03-20 03:00:00 1984-03-18 03:00:00 1985-03-17 03:00:00 1986-03-16 03:00:00 1987-03-15 03:00:00 1988-03-20 03:00:00 1989-03-19 03:00:00 - 1990-03-18 02:00:00 1991-03-17 02:00:00 1992-03-15 02:00:00 1993-03-21 02:00:00 - 1994-03-20 02:00:00 1995-03-19 02:00:00 1996-03-17 02:00:00 1997-03-16 02:00:00 - 1998-03-15 02:00:00 1999-03-21 02:00:00 + 1990-03-18 03:00:00 1991-03-17 03:00:00 1992-03-15 03:00:00 1993-03-21 03:00:00 + 1994-03-20 03:00:00 1995-03-19 03:00:00 1996-03-17 03:00:00 1997-03-16 03:00:00 + 1998-03-15 03:00:00 1999-03-21 03:00:00 =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 19700927T020000 - FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=9 Time zone 2 PHP & SQL results are identical (-: +PHP Result: + + 1970-09-27 02:00:00 1971-09-26 02:00:00 1972-09-24 02:00:00 1973-09-30 02:00:00 + 1974-09-29 02:00:00 1975-09-28 02:00:00 1976-09-26 02:00:00 1977-09-25 02:00:00 + 1978-09-24 02:00:00 1979-09-30 02:00:00 1980-09-28 02:00:00 1981-09-27 02:00:00 + 1982-09-26 02:00:00 1983-09-25 02:00:00 1984-09-30 02:00:00 1985-09-29 02:00:00 + 1986-09-28 02:00:00 1987-09-27 02:00:00 1988-09-25 02:00:00 1989-09-24 02:00:00 + 1990-09-30 02:00:00 1991-09-29 02:00:00 1992-09-27 02:00:00 1993-09-26 02:00:00 + 1994-09-25 02:00:00 1995-09-24 02:00:00 1996-09-29 02:00:00 1997-09-28 02:00:00 + 1998-09-27 02:00:00 1999-09-26 02:00:00 + +SQL Result: + + 1970-09-27 02:00:00 1971-09-26 02:00:00 1972-09-24 02:00:00 1973-09-30 02:00:00 + 1974-09-29 02:00:00 1975-09-28 02:00:00 1976-09-26 02:00:00 1977-09-25 02:00:00 + 1978-09-24 02:00:00 1979-09-30 02:00:00 1980-09-28 02:00:00 1981-09-27 02:00:00 + 1982-09-26 02:00:00 1983-09-25 02:00:00 1984-09-30 02:00:00 1985-09-29 02:00:00 + 1986-09-28 02:00:00 1987-09-27 02:00:00 1988-09-25 02:00:00 1989-09-24 02:00:00 + 1990-09-30 02:00:00 1991-09-29 02:00:00 1992-09-27 02:00:00 1993-09-26 02:00:00 + 1994-09-25 02:00:00 1995-09-24 02:00:00 1996-09-29 02:00:00 1997-09-28 02:00:00 + 1998-09-27 02:00:00 1999-09-26 02:00:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 19810329T030000 - FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU Time zone 3 PHP & SQL results are identical (-: +PHP Result: + + 1981-03-29 03:00:00 1982-03-28 03:00:00 1983-03-27 03:00:00 1984-03-25 03:00:00 + 1985-03-31 03:00:00 1986-03-30 03:00:00 1987-03-29 03:00:00 1988-03-27 03:00:00 + 1989-03-26 03:00:00 1990-03-25 03:00:00 1991-03-31 03:00:00 1992-03-29 03:00:00 + 1993-03-28 03:00:00 1994-03-27 03:00:00 1995-03-26 03:00:00 1996-03-31 03:00:00 + 1997-03-30 03:00:00 1998-03-29 03:00:00 1999-03-28 03:00:00 2000-03-26 03:00:00 + 2001-03-25 03:00:00 2002-03-31 03:00:00 2003-03-30 03:00:00 2004-03-28 03:00:00 + 2005-03-27 03:00:00 2006-03-26 03:00:00 2007-03-25 03:00:00 2008-03-30 03:00:00 + 2009-03-29 03:00:00 2010-03-28 03:00:00 + +SQL Result: + + 1981-03-29 03:00:00 1982-03-28 03:00:00 1983-03-27 03:00:00 1984-03-25 03:00:00 + 1985-03-31 03:00:00 1986-03-30 03:00:00 1987-03-29 03:00:00 1988-03-27 03:00:00 + 1989-03-26 03:00:00 1990-03-25 03:00:00 1991-03-31 03:00:00 1992-03-29 03:00:00 + 1993-03-28 03:00:00 1994-03-27 03:00:00 1995-03-26 03:00:00 1996-03-31 03:00:00 + 1997-03-30 03:00:00 1998-03-29 03:00:00 1999-03-28 03:00:00 2000-03-26 03:00:00 + 2001-03-25 03:00:00 2002-03-31 03:00:00 2003-03-30 03:00:00 2004-03-28 03:00:00 + 2005-03-27 03:00:00 2006-03-26 03:00:00 2007-03-25 03:00:00 2008-03-30 03:00:00 + 2009-03-29 03:00:00 2010-03-28 03:00:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20000404T010000 - FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;COUNT=15 Time zone 4 PHP & SQL results are identical (-: +PHP Result: + + 2001-04-01 01:00:00 2002-04-07 01:00:00 2003-04-06 01:00:00 2004-04-04 01:00:00 + 2005-04-03 01:00:00 2006-04-02 01:00:00 2007-04-01 01:00:00 2008-04-06 01:00:00 + 2009-04-05 01:00:00 2010-04-04 01:00:00 2011-04-03 01:00:00 2012-04-01 01:00:00 + 2013-04-07 01:00:00 2014-04-06 01:00:00 2015-04-05 01:00:00 + +SQL Result: + + 2001-04-01 01:00:00 2002-04-07 01:00:00 2003-04-06 01:00:00 2004-04-04 01:00:00 + 2005-04-03 01:00:00 2006-04-02 01:00:00 2007-04-01 01:00:00 2008-04-06 01:00:00 + 2009-04-05 01:00:00 2010-04-04 01:00:00 2011-04-03 01:00:00 2012-04-01 01:00:00 + 2013-04-07 01:00:00 2014-04-06 01:00:00 2015-04-05 01:00:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20110905 - FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;COUNT=6 Six Working Days PHP & SQL results are identical (-: +PHP Result: + + 2011-09-05 00:00:00 2011-09-06 00:00:00 2011-09-07 00:00:00 2011-09-08 00:00:00 + 2011-09-09 00:00:00 2011-09-12 00:00:00 + +SQL Result: + + 2011-09-05 00:00:00 2011-09-06 00:00:00 2011-09-07 00:00:00 2011-09-08 00:00:00 + 2011-09-09 00:00:00 2011-09-12 00:00:00 + =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= 20110905 - FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;COUNT=6 Six Working Days PHP & SQL results are identical (-: +PHP Result: + + 2011-09-05 00:00:00 2011-09-06 00:00:00 2011-09-07 00:00:00 2011-09-08 00:00:00 + 2011-09-09 00:00:00 2011-09-12 00:00:00 + +SQL Result: + + 2011-09-05 00:00:00 2011-09-06 00:00:00 2011-09-07 00:00:00 2011-09-08 00:00:00 + 2011-09-09 00:00:00 2011-09-12 00:00:00 + +=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~= +20110831 - RRULE:FREQ=MONTHLY;BYMONTHDAY=31;COUNT=12 +31st of each month +PHP & SQL results are identical (-: +PHP Result: + + 2011-08-31 00:00:00 2011-10-31 00:00:00 2011-12-31 00:00:00 2012-01-31 00:00:00 + 2012-03-31 00:00:00 2012-05-31 00:00:00 2012-07-31 00:00:00 2012-08-31 00:00:00 + 2012-10-31 00:00:00 2012-12-31 00:00:00 2013-01-31 00:00:00 2013-03-31 00:00:00 + +SQL Result: + + 2011-08-31 00:00:00 2011-10-31 00:00:00 2011-12-31 00:00:00 2012-01-31 00:00:00 + 2012-03-31 00:00:00 2012-05-31 00:00:00 2012-07-31 00:00:00 2012-08-31 00:00:00 + 2012-10-31 00:00:00 2012-12-31 00:00:00 2013-01-31 00:00:00 2013-03-31 00:00:00 +