Beispiel #1
0
 /**
  * Produce an iCalendar format DURATION for the difference between this an another iCalDate
  *
  * @param date $from The start of the period
  * @return string The date difference, as an iCalendar duration format
  */
 public function DateDifference($from)
 {
     if (!is_object($from)) {
         $from = new iCalDate($from);
     }
     if ($from->_epoch < $this->_epoch) {
         /** One way to simplify is to always go for positive differences */
         return "-" . $from->DateDifference($self);
     }
     //    if ( $from->_yy == $this->_yy && $from->_mo == $this->_mo ) {
     /** Also somewhat simpler if we can use seconds */
     $diff = $from->_epoch - $this->_epoch;
     $result = "";
     if ($diff >= 86400) {
         $result = intval($diff / 86400);
         $diff = $diff % 86400;
         if ($diff == 0 && $result % 7 == 0) {
             // Duration is an integer number of weeks.
             $result .= intval($result / 7) . "W";
             return $result;
         }
         $result .= "D";
     }
     $result = "P" . $result . "T";
     if ($diff >= 3600) {
         $result .= intval($diff / 3600) . "H";
         $diff = $diff % 3600;
     }
     if ($diff >= 60) {
         $result .= intval($diff / 60) . "M";
         $diff = $diff % 60;
     }
     if ($diff > 0) {
         $result .= intval($diff) . "S";
     }
     return $result;
     //    }
     /**
     * From an intense reading of RFC2445 it appears that durations which are not expressible
     * in Weeks/Days/Hours/Minutes/Seconds are invalid.
     *  ==> This code is not needed then :-)
     $yy = $from->_yy - $this->_yy;
     $mo = $from->_mo - $this->_mo;
     $dd = $from->_dd - $this->_dd;
     $hh = $from->_hh - $this->_hh;
     $mi = $from->_mi - $this->_mi;
     $ss = $from->_ss - $this->_ss;
     
     if ( $ss < 0 ) {  $mi -= 1;   $ss += 60;  }
     if ( $mi < 0 ) {  $hh -= 1;   $mi += 60;  }
     if ( $hh < 0 ) {  $dd -= 1;   $hh += 24;  }
     if ( $dd < 0 ) {  $mo -= 1;   $dd += $this->DaysInMonth();  } // Which will use $this->_(mo|yy) - seemingly sensible
     if ( $mo < 0 ) {  $yy -= 1;   $mo += 12;  }
     
     $result = "";
     if ( $yy > 0) {    $result .= $yy."Y";   }
     if ( $mo > 0) {    $result .= $mo."M";   }
     if ( $dd > 0) {    $result .= $dd."D";   }
     $result .= "T";
     if ( $hh > 0) {    $result .= $hh."H";   }
     if ( $mi > 0) {    $result .= $mi."M";   }
     if ( $ss > 0) {    $result .= $ss."S";   }
     return $result;
     */
 }
Beispiel #2
0
 /**
  * Processes the array of $relative_days to $base and removes any
  * which are not within the scope of our rule.
  */
 function WithinScope($base, $relative_days)
 {
     $ok_days = array();
     $ptr = $this->_current;
     //    dbg_error_log( "RRule", " WithinScope: Processing list of %d days relative to %s", count($relative_days), $base->Render() );
     foreach ($relative_days as $day => $v) {
         $test = new iCalDate($base);
         $days_in_month = $test->DaysInMonth();
         //      dbg_error_log( "RRule", " WithinScope: Testing for day %d based on %s, with %d days in month", $day, $test->Render(), $days_in_month );
         if ($day > $days_in_month) {
             $test->SetMonthDay($days_in_month);
             $test->AddDays(1);
             $day -= $days_in_month;
             $test->SetMonthDay($day);
         } else {
             if ($day < 1) {
                 $test->SetMonthDay(1);
                 $test->AddDays(-1);
                 $days_in_month = $test->DaysInMonth();
                 $day += $days_in_month;
                 $test->SetMonthDay($day);
             } else {
                 $test->SetMonthDay($day);
             }
         }
         //      dbg_error_log( "RRule", " WithinScope: Testing if %s is within scope", count($relative_days), $test->Render() );
         if (isset($this->_part['UNTIL']) && $test->GreaterThan($this->_part['UNTIL'])) {
             $this->_finished = true;
             return $ok_days;
         }
         // if ( $this->_current >= 0 && $test->LessThan($this->_dates[$this->_current]) ) continue;
         if (!$test->LessThan($this->_first)) {
             //        dbg_error_log( "RRule", " WithinScope: Looks like %s is within scope", $test->Render() );
             $ok_days[$day] = $test;
             $ptr++;
         }
         if (isset($this->_part['COUNT']) && $ptr >= $this->_part['COUNT']) {
             $this->_finished = true;
             return $ok_days;
         }
     }
     return $ok_days;
 }