File: test-RRULE-v2.php

package info (click to toggle)
davical 1.1.12-2.3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,020 kB
  • sloc: php: 19,361; sql: 4,514; perl: 3,524; sh: 554; javascript: 162; makefile: 85
file content (155 lines) | stat: -rwxr-xr-x 6,681 bytes parent folder | download | duplicates (3)
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);