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 @@ -43,6 +43,7 @@ private $initialMonth; private $initialYear; private $baseYear; + private $isAllDay; const FREQUENCY_SECONDLY = 'SECONDLY'; const FREQUENCY_MINUTELY = 'MINUTELY'; @@ -334,15 +335,26 @@ $this->initialMonth = $this->cursorMonth; $this->initialYear = $this->cursorYear; + + $by_hour = $this->getByHour(); + $by_minute = $this->getByMinute(); + $by_second = $this->getBySecond(); + + $scale = $this->getFrequencyScale(); + + // We return all-day events if the start date is an all-day event and we + // don't have more granular selectors or a more granular frequency. + $this->isAllDay = $date->getIsAllDay() + && !$by_hour + && !$by_minute + && !$by_second + && ($scale > self::SCALE_HOURLY); } public function getNextEvent($cursor) { - $date = $this->getStartDateTime(); - $this->baseYear = $this->cursorYear; - $all_day = $date->getIsAllDay(); - if ($all_day) { + if ($this->isAllDay) { $this->nextDay(); } else { $this->nextSecond(); @@ -354,7 +366,7 @@ ->setMonth($this->stateMonth) ->setDay($this->stateDay); - if ($all_day) { + if ($this->isAllDay) { $result->setIsAllDay(true); } else { $result 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 @@ -303,6 +303,15 @@ '20091228', ); + $tests[] = array( + 'BYHOUR' => array(6, 18), + ); + $expect[] = array( + '19970902T060000Z', + '19970902T180000Z', + '19980902T060000Z', + ); + $this->assertRules( array( 'FREQ' => 'YEARLY', @@ -354,6 +363,11 @@ $rrule->setByWeekNumber($by_weekno); } + $by_hour = idx($options, 'BYHOUR'); + if ($by_hour) { + $rrule->setByHour($by_hour); + } + $set = id(new PhutilCalendarRecurrenceSet()) ->addSource($rrule);