public function getOccurrencesBetween($startDate, $endDate, $limit = NULL)
{
$thisClone = clone $this;
// Enforce consistent time zones. Date comparisons don't require them, but +P1D loop does.
if ($tz = $thisClone->getTimeZone()) {
$startDate->setTimeZone($tz);
$endDate->setTimeZone($tz);
}
$occurrences = array();
if ($endDate <= $startDate) {
return $occurrences;
}
// if existing UNTIL < startDate - we have nothing
if (isset($thisClone->until) && $thisClone->until < $startDate) {
return $occurrences;
} elseif (!isset($thisClone->until)) {
$thisClone->until = $endDate;
}
$thisClone->generateOccurrences();
$all_occurrences = $thisClone->occurrences;
// nothing found in $thisClone->generateOccurrences();
if (empty($all_occurrences)) {
return $occurrences;
}
$last_occurrence = end($all_occurrences);
// if we've hit the rangeLimit, restart looking but start at this last_occurrence
if ($thisClone->rangeLimit == count($all_occurrences) && $thisClone->startDate != $last_occurrence) {
$thisClone->startDate = clone $last_occurrence;
if (isset($thisClone->limit)) {
$thisClone->limit = $thisClone->limit - 200;
}
// clear all occurrences before our start date
foreach ($thisClone->occurrences as $key => $occurrence) {
if ($occurrence < $startDate) {
unset($thisClone->occurrences[$key]);
}
}
return $thisClone->getOccurrencesBetween($startDate, $endDate, $limit);
}
// if our last occurrence is is before our startDate, we have nothing
if ($last_occurrence < $startDate) {
return $occurrences;
}
// we have something to report, so reset our array pointer
reset($all_occurrences);
$count = 0;
foreach ($all_occurrences as $occurrence) {
// fastforward our pointer to where it's >= startDate
if ($occurrence < $startDate) {
continue;
}
// if current occurence is past our endDate - we're done
if ($occurrence > $endDate) {
break;
}
// if we reach getOccurrencesBetween()'s limit - we're done
if (NULL != $limit && ++$count > $limit) {
break;
}
$occurrences[] = $occurrence;
}
return $occurrences;
}