public function applyInternalEffects($object, $value)
 {
     $rrule = id(new PhutilCalendarRecurrenceRule())->setFrequency($value);
     // If the user creates a monthly event on the 29th, 30th or 31st of a
     // month, it means "the 30th of every month" as far as the RRULE is
     // concerned. Such an event will not occur on months with fewer days.
     // This is surprising, and proably not what the user wants. Instead,
     // schedule these events relative to the end of the month: on the "-1st",
     // "-2nd" or "-3rd" day of the month. For example, a monthly event on
     // the 31st of a 31-day month translates to "every month, on the last
     // day of the month".
     if ($value == PhutilCalendarRecurrenceRule::FREQUENCY_MONTHLY) {
         $start_datetime = $object->newStartDateTime();
         $y = $start_datetime->getYear();
         $m = $start_datetime->getMonth();
         $d = $start_datetime->getDay();
         if ($d >= 29) {
             $year_map = PhutilCalendarRecurrenceRule::getYearMap($y, PhutilCalendarRecurrenceRule::WEEKDAY_MONDAY);
             $month_days = $year_map['monthDays'][$m];
             $schedule_on = -($month_days + 1 - $d);
             $rrule->setByMonthDay(array($schedule_on));
         }
     }
     $object->setRecurrenceRule($rrule);
 }
 public function newRecurrenceRule()
 {
     if ($this->isChildEvent()) {
         return $this->getParentEvent()->newRecurrenceRule();
     }
     if (!$this->getIsRecurring()) {
         return null;
     }
     $dict = $this->getParameter('recurrenceRule');
     if (!$dict) {
         return null;
     }
     $rrule = PhutilCalendarRecurrenceRule::newFromDictionary($dict);
     $start = $this->newStartDateTime();
     $rrule->setStartDateTime($start);
     $until = $this->newUntilDateTime();
     if ($until) {
         $rrule->setUntil($until);
     }
     $count = $this->getRecurrenceCount();
     if ($count) {
         $rrule->setCount($count);
     }
     return $rrule;
 }