1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#!/usr/bin/php
<?php
if ( @file_exists('../../awl/inc/AWLUtilities.php') ) {
set_include_path('../inc:../htdocs:../../awl/inc');
}
else {
set_include_path('../inc:../htdocs:/usr/share/awl/inc');
}
require_once("always.php");
$c->dbg = array();
require_once("RRule.php");
require_once('AwlQuery.php');
# Check database timezone
$qry = new AwlQuery();
$qry->QDo("SHOW TIMEZONE");
$row = $qry->Fetch();
$initial_tz = $row->TimeZone;
echo "Database Time Zone: $initial_tz\n";
@header("Content-Type: text/plain; charset=UTF-8");
echo <<<EOTXT
Testing the RRule v2 Library
EOTXT;
class RRuleTest {
var $dtstart;
var $recur;
var $description;
var $result_description;
var $PHP_time;
var $SQL_time;
private $result_limit;
private $tz;
function __construct( $description, $start, $recur, $result_description = null ) {
$this->description = $description;
$this->dtstart = $start;
$this->recur = $recur;
$this->result_description = $result_description;
$this->result_limit = 30;
if ( preg_match('/^.*? (.*)$/', $this->dtstart, $matches) ) {
$this->tz = $matches[1];
}
}
function PHPTest() {
$result = '';
$start = microtime(true);
$rule = new RepeatRule( $this->dtstart, $this->recur );
$i = 0;
while( $date = $rule->next() ) {
if ( ($i++ % 4) == 0 ) $result .= "\n";
$result .= " " . $date->format('Y-m-d H:i:s');
if ( $i >= $this->result_limit ) break;
}
$this->PHP_time = microtime(true) - $start;
return $result;
}
function SQLTest() {
$qry = new AwlQuery;
global $initial_tz;
# This is a hack to get the output time to be in "local time" so that we
# get the same time out of the PHP code to allow the diff between the
# results to work.
$changed_tz = 0;
if (isset($this->tz) && $this->tz != $initial_tz) {
echo "Setting database time zone to: $this->tz\n";
$qry->QDo("SET TIMEZONE TO :tz", array( ':tz' => $this->tz ));
$changed_tz = 1;
}
$result = '';
$sql = "SELECT event_instances::timestamp AS event_date FROM event_instances(:dtstart,:rrule) LIMIT ".$this->result_limit;
$start = microtime(true);
$qry->SetSql($sql);
$qry->Bind(array( ':dtstart' => $this->dtstart, ':rrule' => $this->recur) );
// printf( "%s\n", $qry->querystring);
if ( $qry->Exec("test") && $qry->rows() > 0 ) {
$i = 0;
while( $row = $qry->Fetch() ) {
if ( ($i++ % 4) == 0 ) $result .= "\n";
$result .= " " . $row->event_date;
}
}
$this->SQL_time = microtime(true) - $start;
if ($changed_tz) {
$qry->QDo("SET TIMEZONE TO '$initial_tz'");
}
return $result;
}
}
$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 4 events", "20061103T160000", "RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4" )
, 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( "The working days of each month", "20061107T113000", "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;UNTIL=20070101T000000" )
, new RRuleTest( "The last working day of each month", "20061107T113000", "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1;COUNT=30" )
, new RRuleTest( "Every working day", "20081020T103000", "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;COUNT=30" )
, new RRuleTest( "Every working day", "20081020T110000", "RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;COUNT=30" )
, new RRuleTest( "The last day of each month", "20110831", "RRULE:FREQ=MONTHLY;BYMONTHDAY=-1" )
, new RRuleTest( "1st Tuesday, 2nd Wednesday, 3rd Thursday & 4th Friday, every March, June, September, October and December (SQL is wrong)", "20081001T133000", "RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU,2WE,3TH,4FR;BYMONTH=3,6,9,10,12" )
, new RRuleTest( "Every tuesday and friday", "20081017T084500", "RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=TU,FR;COUNT=30" )
, new RRuleTest( "Every tuesday and friday", "20081017T084500", "RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,FR;COUNT=30" )
, new RRuleTest( "Every tuesday and friday", "20081017T084500", "RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=TU,FR;COUNT=30" )
, new RRuleTest( "Time zone 1", "19700315T030000 Pacific/Auckland", "FREQ=YEARLY;INTERVAL=1;BYDAY=3SU;BYMONTH=3" )
, new RRuleTest( "Time zone 2", "19700927T020000", "FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=9" )
, new RRuleTest( "Time zone 3", "19810329T030000", "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU" )
, 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" )
, new RRuleTest( "Expand over daylight savings change day forward - but no time change (2020-09-27)", "20200925T011500 Pacific/Auckland", "RRULE:FREQ=DAILY;COUNT=12" )
, new RRuleTest( "Expand over daylight savings change forward - time jump (2020-09-27) - According to RFC 5545, because 02:15 doesn't exist on 2020-09-27, that day should be skipped", "20200925T021500 Pacific/Auckland", "RRULE:FREQ=DAILY;COUNT=12" )
, new RRuleTest( "Monthly, from the 29th of Feb", "20120229", "RRULE:FREQ=MONTHLY;COUNT=12" )
);
foreach( $tests AS $k => $test ) {
echo "=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=\n";
echo "$test->dtstart - $test->recur\n";
echo "$test->description\n";
$php_result = $test->PHPTest();
$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);
echo "PHP Result:\n$php_result\n\n";
echo "SQL Result:\n$sql_result\n\n"; // Still under development
}
}
exit(0);
|