Adds a number of seconds or units to this date, returning a new Date
object.
public add ( $factor ) |
/** * Return the next past or future Span for the time that this Repeater represents * pointer - Symbol representing which temporal direction to fetch the next day * must be either :past or :future */ public function next($pointer = 'future') { parent::next($pointer); $halfDay = 3600 * 12; $fullDay = 3600 * 24; $first = false; if (!$this->currentTime) { $first = true; $midnight = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day)); $yesterdayMidnight = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day - 1)); $tomorrowMidnight = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day + 1)); if ($pointer == 'future') { if ($this->ambiguous) { foreach (array($midnight->add($this->type), $midnight->add($halfDay + $this->type), $tomorrowMidnight->add($this->type)) as $t) { if ($t->compareDateTime($this->now) >= 0) { $this->currentTime = $t; break; } } } else { foreach (array($midnight->add($this->type), $tomorrowMidnight->add($this->type)) as $t) { if ($t->compareDateTime($this->now) >= 0) { $this->currentTime = $t; break; } } } } elseif ($pointer == 'past') { if ($this->ambiguous) { foreach (array($midnight->add($halfDay + $this->type), $midnight->add($this->type), $yesterdayMidnight->add($this->type * 2)) as $t) { if ($t->compareDateTime($this->now) <= 0) { $this->currentTime = $t; break; } } } else { foreach (array($midnight->add($this->type), $yesterdayMidnight->add($this->type)) as $t) { if ($t->compareDateTime($this->now) <= 0) { $this->currentTime = $t; break; } } } } if (!$this->currentTime) { throw new Horde_Date_Repeater_Exception('Current time cannot be null at this point'); } } if (!$first) { $increment = $this->ambiguous ? $halfDay : $fullDay; $this->currentTime->sec += $pointer == 'future' ? $increment : -$increment; } return new Horde_Date_Span($this->currentTime, $this->currentTime->add(1)); }
public function this($pointer = 'future') { parent::this($pointer); switch ($pointer) { case 'future': $hourStart = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'hour' => $this->now->hour, 'min' => $this->now->min + 1)); $hourEnd = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'hour' => $this->now->hour + 1)); break; case 'past': $hourStart = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'hour' => $this->now->hour)); $hourEnd = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'hour' => $this->now->hour, 'min' => $this->now->min)); break; case 'none': $hourStart = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'hour' => $this->now->hour)); $hourEnd = $hourStart->add(array('hour' => 1)); break; } return new Horde_Date_Span($hourStart, $hourEnd); }
public function testDateMath() { $d = new Horde_Date('2008-01-01 00:00:00'); $this->assertEquals('2007-12-31 00:00:00', (string) $d->sub(array('day' => 1))); $this->assertEquals('2009-01-01 00:00:00', (string) $d->add(array('year' => 1))); $this->assertEquals('2008-01-01 04:00:00', (string) $d->add(14400)); $span = new Horde_Date_Span('2006-01-01 00:00:00', '2006-08-16 00:00:00'); $this->assertEquals('2006-04-24 11:30:00', (string) $span->begin->add($span->width() / 2)); }
/** * Creates a new event that represents an exception to a recurring event. * * @param Kronolith_Event $event The original recurring event. * @param Kronolith_Event $copy If present, contains a copy of $event, but * with changes from edited event form. * @param stdClass $attributes The attributes passed from the client. * Expected to contain rstart and rend or * rday that represents the original * starting/ending date of the instance. * * @return Kronolith_Event The event representing the exception */ protected function _copyEvent(Kronolith_Event $event, Kronolith_Event $copy = null, $attributes = null) { if (empty($copy)) { $copy = clone $event; } if ($attributes->rstart) { $rstart = new Horde_Date($attributes->rstart); $rstart->setTimezone($event->start->timezone); $rend = new Horde_Date($attributes->rend); $rend->setTimezone($event->end->timezone); } else { $rstart = new Horde_Date($attributes->rday); $rstart->setTimezone($event->start->timezone); $rstart->hour = $event->start->hour; $rstart->min = $event->start->min; $rend = $rstart->add($event->getDuration); $rend->setTimezone($event->end->timezone); $rend->hour = $event->end->hour; $rend->min = $event->end->min; } $uid = $event->uid; $otime = $event->start->strftime('%T'); // Create new event for the exception $nevent = $event->getDriver()->getEvent(); $nevent->baseid = $uid; $nevent->exceptionoriginaldate = new Horde_Date($rstart->strftime('%Y-%m-%d') . 'T' . $otime); $nevent->exceptionoriginaldate->setTimezone($event->start->timezone); $nevent->creator = $event->creator; $nevent->title = $copy->title; $nevent->description = $copy->description; $nevent->location = $copy->location; $nevent->private = $copy->private; $nevent->url = $copy->url; $nevent->status = $copy->status; $nevent->attendees = $copy->attendees; $nevent->setResources($copy->getResources()); $nevent->start = $rstart; $nevent->end = $rend; $nevent->initialized = true; return $nevent; }
/** * Add a number of seconds to this span, returning the new span */ public function add($factor) { return new Horde_Date_Span($this->begin->add($factor), $this->end->add($factor)); }
/** * Test if the weekday of the given timestamp is the nth occurence of this * weekday within its month, where '5' indicates the last occurrence even if * there is less than five occurrences. * * @param integer $timestamp The timestamp to check. * @param integer $occurence 1 to 5, where 5 indicates the final occurrence * during the month if that day of the week does * not occur 5 times * @return boolean */ protected static function _isNthOcurrenceOfWeekdayInMonth($timestamp, $occurence) { $original = new Horde_Date($timestamp); $original->setTimezone('UTC'); if ($occurence == 5) { $modified = $original->add(array('mday' => 7)); return $modified->month > $original->month; } else { $modified = $original->sub(array('mday' => 7 * $occurence)); $modified2 = $original->sub(array('mday' => 7 * ($occurence - 1))); return $modified->month < $original->month && $modified2->month == $original->month; } }
/** * Calculate a timestamp and return it along with the field name * * @param string $type The timestamp parameter. * * @return integer 'timestamp' intended field value or null */ private function _calc_expiration($type) { if (empty($this->_params[$type . '_expiration_window'])) { return null; } else { $now = new Horde_Date(time()); return $now->add(array('mday' => $this->_params[$type . '_expiration_window']))->timestamp(); } }
public function this($context = 'future') { parent::this($context); $rangeStart = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'sec' => $this->range[0])); $this->currentSpan = new Horde_Date_Span($rangeStart, $rangeStart->add($this->range[1] - $this->range[0])); return $this->currentSpan; }
/** * Finds the next recurrence of this event that's after $afterDate. * * @param Horde_Date|string $after Return events after this date. * * @return Horde_Date|boolean The date of the next recurrence or false * if the event does not recur after * $afterDate. */ public function nextRecurrence($after) { if (!$after instanceof Horde_Date) { $after = new Horde_Date($after); } else { $after = clone $after; } // Make sure $after and $this->start are in the same TZ $after->setTimezone($this->start->timezone); if ($this->start->compareDateTime($after) >= 0) { return clone $this->start; } if ($this->recurInterval == 0 && empty($this->rdates)) { return false; } switch ($this->getRecurType()) { case self::RECUR_DAILY: $diff = $this->start->diff($after); $recur = ceil($diff / $this->recurInterval); if ($this->recurCount && $recur >= $this->recurCount) { return false; } $recur *= $this->recurInterval; $next = $this->start->add(array('day' => $recur)); if ((!$this->hasRecurEnd() || $next->compareDateTime($this->recurEnd) <= 0) && $next->compareDateTime($after) >= 0) { return $next; } break; case self::RECUR_WEEKLY: if (empty($this->recurData)) { return false; } $start_week = Horde_Date_Utils::firstDayOfWeek($this->start->format('W'), $this->start->year); $start_week->timezone = $this->start->timezone; $start_week->hour = $this->start->hour; $start_week->min = $this->start->min; $start_week->sec = $this->start->sec; // Make sure we are not at the ISO-8601 first week of year while // still in month 12...OR in the ISO-8601 last week of year while // in month 1 and adjust the year accordingly. $week = $after->format('W'); if ($week == 1 && $after->month == 12) { $theYear = $after->year + 1; } elseif ($week >= 52 && $after->month == 1) { $theYear = $after->year - 1; } else { $theYear = $after->year; } $after_week = Horde_Date_Utils::firstDayOfWeek($week, $theYear); $after_week->timezone = $this->start->timezone; $after_week_end = clone $after_week; $after_week_end->mday += 7; $diff = $start_week->diff($after_week); $interval = $this->recurInterval * 7; $repeats = floor($diff / $interval); if ($diff % $interval < 7) { $recur = $diff; } else { /** * If the after_week is not in the first week interval the * search needs to skip ahead a complete interval. The way it is * calculated here means that an event that occurs every second * week on Monday and Wednesday with the event actually starting * on Tuesday or Wednesday will only have one incidence in the * first week. */ $recur = $interval * ($repeats + 1); } if ($this->hasRecurCount()) { $recurrences = 0; /** * Correct the number of recurrences by the number of events * that lay between the start of the start week and the * recurrence start. */ $next = clone $start_week; while ($next->compareDateTime($this->start) < 0) { if ($this->recurOnDay((int) pow(2, $next->dayOfWeek()))) { $recurrences--; } ++$next->mday; } if ($repeats > 0) { $weekdays = $this->recurData; $total_recurrences_per_week = 0; while ($weekdays > 0) { if ($weekdays % 2) { $total_recurrences_per_week++; } $weekdays = ($weekdays - $weekdays % 2) / 2; } $recurrences += $total_recurrences_per_week * $repeats; } } $next = clone $start_week; $next->mday += $recur; while ($next->compareDateTime($after) < 0 && $next->compareDateTime($after_week_end) < 0) { if ($this->hasRecurCount() && $next->compareDateTime($after) < 0 && $this->recurOnDay((int) pow(2, $next->dayOfWeek()))) { $recurrences++; } ++$next->mday; } if ($this->hasRecurCount() && $recurrences >= $this->recurCount) { return false; } if (!$this->hasRecurEnd() || $next->compareDateTime($this->recurEnd) <= 0) { if ($next->compareDateTime($after_week_end) >= 0) { return $this->nextRecurrence($after_week_end); } while (!$this->recurOnDay((int) pow(2, $next->dayOfWeek())) && $next->compareDateTime($after_week_end) < 0) { ++$next->mday; } if (!$this->hasRecurEnd() || $next->compareDateTime($this->recurEnd) <= 0) { if ($next->compareDateTime($after_week_end) >= 0) { return $this->nextRecurrence($after_week_end); } else { return $next; } } } break; case self::RECUR_MONTHLY_DATE: $start = clone $this->start; if ($after->compareDateTime($start) < 0) { $after = clone $start; } else { $after = clone $after; } // If we're starting past this month's recurrence of the event, // look in the next month on the day the event recurs. if ($after->mday > $start->mday) { ++$after->month; $after->mday = $start->mday; } // Adjust $start to be the first match. $offset = $after->month - $start->month + ($after->year - $start->year) * 12; $offset = floor(($offset + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval; if ($this->recurCount && $offset / $this->recurInterval >= $this->recurCount) { return false; } $start->month += $offset; $count = $offset / $this->recurInterval; do { if ($this->recurCount && $count++ >= $this->recurCount) { return false; } // Bail if we've gone past the end of recurrence. if ($this->hasRecurEnd() && $this->recurEnd->compareDateTime($start) < 0) { return false; } if ($start->isValid()) { return $start; } // If the interval is 12, and the date isn't valid, then we // need to see if February 29th is an option. If not, then the // event will _never_ recur, and we need to stop checking to // avoid an infinite loop. if ($this->recurInterval == 12 && ($start->month != 2 || $start->mday > 29)) { return false; } // Add the recurrence interval. $start->month += $this->recurInterval; } while (true); break; case self::RECUR_MONTHLY_WEEKDAY: // Start with the start date of the event. $estart = clone $this->start; // What day of the week, and week of the month, do we recur on? if (isset($this->recurNthDay)) { $nth = $this->recurNthDay; $weekday = log($this->recurData, 2); } else { $nth = ceil($this->start->mday / 7); $weekday = $estart->dayOfWeek(); } // Adjust $estart to be the first candidate. $offset = $after->month - $estart->month + ($after->year - $estart->year) * 12; $offset = floor(($offset + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval; // Adjust our working date until it's after $after. $estart->month += $offset - $this->recurInterval; $count = $offset / $this->recurInterval; do { if ($this->recurCount && $count++ >= $this->recurCount) { return false; } $estart->month += $this->recurInterval; $next = clone $estart; $next->setNthWeekday($weekday, $nth); if ($next->compareDateTime($after) < 0) { // We haven't made it past $after yet, try again. continue; } if ($this->hasRecurEnd() && $next->compareDateTime($this->recurEnd) > 0) { // We've gone past the end of recurrence; we can give up // now. return false; } // We have a candidate to return. break; } while (true); return $next; case self::RECUR_YEARLY_DATE: // Start with the start date of the event. $estart = clone $this->start; $after = clone $after; if ($after->month > $estart->month || $after->month == $estart->month && $after->mday > $estart->mday) { ++$after->year; $after->month = $estart->month; $after->mday = $estart->mday; } // Seperate case here for February 29th if ($estart->month == 2 && $estart->mday == 29) { while (!Horde_Date_Utils::isLeapYear($after->year)) { ++$after->year; } } // Adjust $estart to be the first candidate. $offset = $after->year - $estart->year; if ($offset > 0) { $offset = floor(($offset + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval; $estart->year += $offset; } // We've gone past the end of recurrence; give up. if ($this->recurCount && $offset >= $this->recurCount) { return false; } if ($this->hasRecurEnd() && $this->recurEnd->compareDateTime($estart) < 0) { return false; } return $estart; case self::RECUR_YEARLY_DAY: // Check count first. $dayofyear = $this->start->dayOfYear(); $count = ($after->year - $this->start->year) / $this->recurInterval + 1; if ($this->recurCount && ($count > $this->recurCount || $count == $this->recurCount && $after->dayOfYear() > $dayofyear)) { return false; } // Start with a rough interval. $estart = clone $this->start; $estart->year += floor($count - 1) * $this->recurInterval; // Now add the difference to the required day of year. $estart->mday += $dayofyear - $estart->dayOfYear(); // Add an interval if the estimation was wrong. if ($estart->compareDate($after) < 0) { $estart->year += $this->recurInterval; $estart->mday += $dayofyear - $estart->dayOfYear(); } // We've gone past the end of recurrence; give up. if ($this->hasRecurEnd() && $this->recurEnd->compareDateTime($estart) < 0) { return false; } return $estart; case self::RECUR_YEARLY_WEEKDAY: // Start with the start date of the event. $estart = clone $this->start; // What day of the week, and week of the month, do we recur on? if (isset($this->recurNthDay)) { $nth = $this->recurNthDay; $weekday = log($this->recurData, 2); } else { $nth = ceil($this->start->mday / 7); $weekday = $estart->dayOfWeek(); } // Adjust $estart to be the first candidate. $offset = floor(($after->year - $estart->year + $this->recurInterval - 1) / $this->recurInterval) * $this->recurInterval; // Adjust our working date until it's after $after. $estart->year += $offset - $this->recurInterval; $count = $offset / $this->recurInterval; do { if ($this->recurCount && $count++ >= $this->recurCount) { return false; } $estart->year += $this->recurInterval; $next = clone $estart; $next->setNthWeekday($weekday, $nth); if ($next->compareDateTime($after) < 0) { // We haven't made it past $after yet, try again. continue; } if ($this->hasRecurEnd() && $next->compareDateTime($this->recurEnd) > 0) { // We've gone past the end of recurrence; we can give up // now. return false; } // We have a candidate to return. break; } while (true); return $next; } // fall-back to RDATE properties if (!empty($this->rdates)) { $next = clone $this->start; foreach ($this->rdates as $rdate) { $next->year = $rdate->year; $next->month = $rdate->month; $next->mday = $rdate->mday; if ($next->compareDateTime($after) > 0) { return $next; } } } // We didn't find anything, the recurType was bad, or something else // went wrong - return false. return false; }
/** * Reads the search form submitted and return the search criteria * */ protected function _readSearchForm() { $perms = $GLOBALS['injector']->getInstance('Horde_Perms'); $vars = $this->vars; $criteria = array(); if ($GLOBALS['registry']->isAdmin(array('permission' => 'hermes:review'))) { if (!empty($vars->employees[0])) { $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create(); if (!$auth->hasCapability('list')) { $criteria['employee'] = explode(',', $vars->employees[0]); if (empty($criteria['employee'])) { unset($criteria['employee']); } } else { $criteria['employee'] = $vars->employees; } } } else { $criteria['employee'] = $GLOBALS['registry']->getAuth(); } if (!empty($vars->client)) { $criteria['client'] = $vars->client; } if (!empty($vars->type)) { $criteria['jobtype'] = $vars->type; } if (!empty($vars->costobject)) { $criteria['costobject'] = $vars->costobject; } if (!empty($vars->after_date)) { $dt = new Horde_Date($vars->after_date); $criteria['start'] = $dt->timestamp(); } if (!empty($vars->before_date)) { $dt = new Horde_Date($vars->before_date); $criteria['end'] = $dt->add(86400)->timestamp(); } if ($vars->billable !== '') { $criteria['billable'] = $vars->billable; } if ($vars->submitted !== '') { $criteria['submitted'] = $vars->submitted; } if ($vars->exported !== '') { $criteria['exported'] = $vars->exported; } return $criteria; }
public function getSearchCriteria($vars) { if (!$this->isValid() || !$this->isSubmitted()) { return null; } $this->getInfo($vars, $info); $criteria = array(); if ($GLOBALS['registry']->isAdmin(array('permission' => 'hermes:review'))) { if (!empty($info['employees'])) { $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create(); if (!$auth->hasCapability('list')) { $criteria['employee'] = explode(',', $info['employees']); } else { $criteria['employee'] = $info['employees']; } } } else { $criteria['employee'] = $GLOBALS['registry']->getAuth(); } if (!empty($info['clients'])) { $criteria['client'] = $info['clients']; } if (!empty($info['jobtypes'])) { $criteria['jobtype'] = $info['jobtypes']; } if (!empty($info['costobjects'])) { $criteria['costobject'] = $info['costobjects']; } if (!empty($info['start'])) { $dt = new Horde_Date($info['start']); $criteria['start'] = $dt->timestamp(); } if (!empty($info['end'])) { $dt = new Horde_Date($info['end']); $criteria['end'] = $dt->add(86400)->timestamp(); } if (isset($info['submitted']) && $info['submitted'] != '') { $criteria['submitted'] = $info['submitted']; } if (isset($info['exported']) && $info['exported'] != '') { $criteria['exported'] = $info['exported']; } if (isset($info['billable']) && $info['billable'] != '') { $criteria['billable'] = $info['billable']; } return $criteria; }