protected function DateRRuleCalc::get_absolute_bydays in Date 8
Get values for absolute BYDAYs.
For BYDAYs without parameters,like TU,TH (every Tues and Thur), we look for every one of those days during the frequency period. Iterate through periods of a WEEK, MONTH, or YEAR, checking for the days of the week that match our criteria for each week in the period, then jumping ahead to the next week, month, or year, an INTERVAL at a time.
1 call to DateRRuleCalc::get_absolute_bydays()
- DateRRuleCalc::get_byday_results in date_repeat/
lib/ Drupal/ date_repeat/ DateRRuleCalc.php - Processing for BYDAY values.
File
- date_repeat/
lib/ Drupal/ date_repeat/ DateRRuleCalc.php, line 502 - Code to compute the dates that match an iCal RRULE.
Class
Namespace
Drupal\date_repeatCode
protected function get_absolute_bydays($week_days) {
$finished = FALSE;
$this->current_day = clone $this->start_date;
$format = $this->rrule['FREQ'] == 'YEARLY' ? 'Y' : 'n';
$current_period = $this->current_day
->format($format);
// Back up to the beginning of the week in case we are somewhere
// in the middle of the possible week days, needed so we don't
// prematurely jump to the next week. The add_dates() function
// will keep dates outside the range from getting added.
if ($this->current_day
->format('l') != $this->week_start_day) {
date_modify($this->current_day, 'last ' . $this->week_start_day . $this->time_string);
}
while (!$finished) {
$period_finished = FALSE;
while (!$period_finished) {
$moved = FALSE;
foreach ($week_days as $delta => $day) {
// Find the next occurence of each day in this week, only
// add it if we are still in the current month or year. The
// add_current_date() function is insufficient to test whether
// to include this date if we are using a rule like 'every
// other month', so we must explicitly test it here.
// If we're already on the right day, don't jump or we
// will prematurely move into the next week.
if ($this->current_day
->format('l') != $day) {
date_modify($this->current_day, '+1 ' . $day . $this->time_string);
$moved = TRUE;
}
if ($this->rrule['FREQ'] == 'WEEKLY' || $this->current_day
->format($format) == $current_period) {
$this
->add_current_day();
}
}
$finished = $this
->is_finished();
// Make sure we don't get stuck in endless loop if the current
// day never got changed above.
if (!$moved) {
date_modify($this->current_day, '+1 day' . $this->time_string);
}
// If this is a WEEKLY frequency, stop after each week,
// otherwise, stop when we've moved outside the current period.
// Jump to the end of the week, then test the period.
if ($finished || $this->rrule['FREQ'] == 'WEEKLY') {
$period_finished = TRUE;
}
elseif ($this->rrule['FREQ'] != 'WEEKLY' && $this->current_day
->format($format) != $current_period) {
$period_finished = TRUE;
}
}
if ($finished) {
continue;
}
// We'll be at the end of a week, month, or year when
// we get to this point in the code.
// Go back to the beginning of this period before we jump, to
// ensure we jump to the first day of the next period.
switch ($this->rrule['FREQ']) {
case 'WEEKLY':
date_modify($this->current_day, '+1 ' . $this->week_start_day . $this->time_string);
date_modify($this->current_day, '-1 week' . $this->time_string);
break;
case 'MONTHLY':
date_modify($this->current_day, '-' . ($this->current_day
->format('j') - 1) . ' days' . $this->time_string);
date_modify($this->current_day, '-1 month' . $this->time_string);
break;
case 'YEARLY':
date_modify($this->current_day, '-' . $this->current_day
->format('z') . ' days' . $this->time_string);
date_modify($this->current_day, '-1 year' . $this->time_string);
break;
}
// Jump ahead to the next period to be evaluated.
$this->current_day
->add($this->jump);
$current_period = $this->current_day
->format($format);
$finished = $this
->is_finished();
}
}