diff --git a/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php b/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php --- a/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php +++ b/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php @@ -572,17 +572,22 @@ // month", so we need to expand the month set if the constraint is present. $by_monthday = $this->getByMonthDay(); + // Likewise, we need to generate all months if we have BYYEARDAY. + $by_yearday = $this->getByYearDay(); + while (!$this->setMonths) { $this->nextYear(); - if ($is_monthly || $by_month || $by_monthday) { + $is_dynamic = $is_monthly + || $by_month + || $by_monthday + || $by_yearday + || ($scale < self::SCALE_MONTHLY); + + if ($is_dynamic) { $months = $this->newMonthsSet( ($is_monthly ? $interval : 1), $by_month); - } else if ($scale < self::SCALE_MONTHLY) { - $months = $this->newMonthsSet( - 1, - array()); } else { $months = array( $this->cursorMonth, @@ -768,8 +773,8 @@ } if ($by_yearday) { - if (empty($by_monthday[$info['yearday']]) && - empty($by_monthday[$info['-yearday']])) { + if (empty($by_yearday[$info['yearday']]) && + empty($by_yearday[$info['-yearday']])) { continue; } } diff --git a/src/parser/calendar/data/__tests__/PhutilCalendarRecurrenceRuleTestCase.php b/src/parser/calendar/data/__tests__/PhutilCalendarRecurrenceRuleTestCase.php --- a/src/parser/calendar/data/__tests__/PhutilCalendarRecurrenceRuleTestCase.php +++ b/src/parser/calendar/data/__tests__/PhutilCalendarRecurrenceRuleTestCase.php @@ -187,6 +187,38 @@ '19980108', ); + $tests[] = array( + 'BYMONTHDAY' => array(1, 3), + 'BYDAY' => array('TU', 'TH'), + ); + $expect[] = array( + '19980101', + '19980203', + '19980303', + ); + + $tests[] = array( + 'BYMONTHDAY' => array(1, 3), + 'BYDAY' => array('TU', 'TH'), + 'BYMONTH' => array(1, 3), + ); + $expect[] = array( + '19980101', + '19980303', + '20010301', + ); + + $tests[] = array( + 'BYYEARDAY' => array(1, 100, 200, 365), + 'COUNT' => 4, + ); + $expect[] = array( + '19971231', + '19980101', + '19980410', + '19980719', + ); + $this->assertRules( array( 'FREQ' => 'YEARLY', @@ -228,6 +260,11 @@ $rrule->setByMonthDay($by_monthday); } + $by_yearday = idx($options, 'BYYEARDAY'); + if ($by_yearday) { + $rrule->setByYearDay($by_yearday); + } + $set = id(new PhutilCalendarRecurrenceSet()) ->addSource($rrule);