protected function buildWeeknoMask($year, $month, $day, array &$masks)
{
$masks['yearday_is_in_weekno'] = array();
// calculate the index of the first wkst day of the year
// 0 means the first day of the year is the wkst day (e.g. wkst is Monday and Jan 1st is a Monday)
// n means there is n days before the first wkst day of the year.
// if n >= 4, this is the first day of the year (even though it started the year before)
$first_wkst = (7 - $masks['weekday_of_1st_yearday'] + $this->wkst) % 7;
if ($first_wkst >= 4) {
$first_wkst_offset = 0;
// Number of days in the year, plus the days we got from last year.
$nb_days = $masks['year_len'] + $masks['weekday_of_1st_yearday'] - $this->wkst;
// $nb_days = $masks['year_len'] + pymod($masks['weekday_of_1st_yearday'] - $this->wkst,7);
} else {
$first_wkst_offset = $first_wkst;
// Number of days in the year, minus the days we left in last year.
$nb_days = $masks['year_len'] - $first_wkst;
}
$nb_weeks = (int) ($nb_days / 7) + (int) ($nb_days % 7 / 4);
// alright now we now when the first week starts
// and the number of weeks of the year
// so we can generate a map of every yearday that are in the weeks
// specified in byweekno
foreach ($this->byweekno as $n) {
if ($n < 0) {
$n = $n + $nb_weeks + 1;
}
if ($n <= 0 || $n > $nb_weeks) {
continue;
}
if ($n > 1) {
$i = $first_wkst_offset + ($n - 1) * 7;
if ($first_wkst_offset != $first_wkst) {
// if week #1 started the previous year
// realign the start of the week
$i = $i - (7 - $first_wkst);
}
} else {
$i = $first_wkst_offset;
}
// now add 7 days into the resultset, stopping either at 7 or
// if we reach wkst before (in the case of short first week of year)
for ($j = 0; $j < 7; $j++) {
$masks['yearday_is_in_weekno'][$i] = true;
$i = $i + 1;
if ($masks['yearday_to_weekday'][$i] == $this->wkst) {
break;
}
}
}
// if we asked for week #1, it's possible that the week #1 of next year
// already started this year. Therefore we need to return also the matching
// days of next year.
if (in_array(1, $this->byweekno)) {
// Check week number 1 of next year as well
// TODO: Check -numweeks for next year.
$i = $first_wkst_offset + $nb_weeks * 7;
if ($first_wkst_offset != $first_wkst) {
$i = $i - (7 - $first_wkst);
}
if ($i < $masks['year_len']) {
// If week starts in next year, we don't care about it.
for ($j = 0; $j < 7; $j++) {
$masks['yearday_is_in_weekno'][$i] = true;
$i += 1;
if ($masks['yearday_to_weekday'][$i] == $this->wkst) {
break;
}
}
}
}
if ($first_wkst_offset) {
// Check last week number of last year as well.
// If first_wkst_offset is 0, either the year started on week start,
// or week number 1 got days from last year, so there are no
// days from last year's last week number in this year.
if (!in_array(-1, $this->byweekno)) {
$weekday_of_1st_yearday = date_create($year - 1 . '-01-01 00:00:00')->format('N');
$first_wkst_offset_last_year = (7 - $weekday_of_1st_yearday + $this->wkst) % 7;
$last_year_len = 365 + is_leap_year($year - 1);
if ($first_wkst_offset_last_year >= 4) {
$first_wkst_offset_last_year = 0;
$nb_weeks_last_year = 52 + (int) (($last_year_len + ($weekday_of_1st_yearday - $this->wkst) % 7) % 7 / 4);
} else {
$nb_weeks_last_year = 52 + (int) (($masks['year_len'] - $first_wkst_offset) % 7 / 4);
}
} else {
$nb_weeks_last_year = -1;
}
if (in_array($nb_weeks_last_year, $this->byweekno)) {
for ($i = 0; $i < $first_wkst_offset; $i++) {
$masks['yearday_is_in_weekno'][$i] = true;
}
}
}
}