Beispiel #1
0
    def get_local_next_event_due_timestamp_for_monthly_schedule(self, instance):
        target_date = None

        while target_date is None:
            current_event = self.memoized_events[instance.current_event_num]

            if current_event.day < -28 or current_event.day == 0 or current_event.day > 31:
                # Negative days are days from the end of the month, with -1
                # being the last day of the month. We don't allow this going
                # past -28 since it's not very useful to do so, and imposing
                # this restriction lets us make the assumption that we can
                # always schedule a negative day.
                raise InvalidMonthlyScheduleConfiguration("Day must be between -28 and 31, and not be 0")

            year_offset = (instance.schedule_iteration_num - 1) / 12
            month_offset = (instance.schedule_iteration_num - 1) % 12

            year = instance.start_date.year + year_offset
            month = instance.start_date.month + month_offset

            days_in_month = calendar.monthrange(year, month)[1]
            if current_event.day > 0:
                if current_event.day > days_in_month:
                    # If the day refers to a date that is not possible to schedule
                    # (for example, February 30th), just move to the next month.
                    instance.schedule_iteration_num += 1
                    instance.current_event_num = 0
                    continue

                target_date = date(year, month, current_event.day)
            else:
                # It's a negative day, which counts back from the last day of the month
                target_date = date(year, month, days_in_month + current_event.day + 1)

        return datetime.combine(target_date, current_event.time)
Beispiel #2
0
    def get_local_next_event_due_timestamp_for_monthly_schedule(
            self, instance):
        if self.repeat_every >= 0:
            raise ValueError(
                "Expected negative value for repeat_every in a monthly schedule"
            )

        target_date = None
        start_date_with_offset = instance.start_date + timedelta(
            days=self.start_offset)

        while target_date is None:
            current_event = self.memoized_events[instance.current_event_num]

            if current_event.day < -28 or current_event.day == 0 or current_event.day > 31:
                # Negative days are days from the end of the month, with -1
                # being the last day of the month. We don't allow this going
                # past -28 since it's not very useful to do so, and imposing
                # this restriction lets us make the assumption that we can
                # always schedule a negative day.
                raise InvalidMonthlyScheduleConfiguration(
                    "Day must be between -28 and 31, and not be 0")

            months_since_start_date = (instance.schedule_iteration_num -
                                       1) * (-1 * self.repeat_every)
            year = start_date_with_offset.year
            month = start_date_with_offset.month + months_since_start_date

            while month > 12:
                year += 1
                month -= 12

            days_in_month = calendar.monthrange(year, month)[1]
            if current_event.day > 0:
                if current_event.day > days_in_month:
                    # If the day refers to a date that is not possible to schedule
                    # (for example, February 30th), just move to the next month.
                    instance.schedule_iteration_num += 1
                    instance.current_event_num = 0
                    continue

                target_date = date(year, month, current_event.day)
            else:
                # It's a negative day, which counts back from the last day of the month
                target_date = date(year, month,
                                   days_in_month + current_event.day + 1)

        local_time, additional_day_offset = current_event.get_time(
            case=self.get_case_or_none(instance))
        return datetime.combine(
            target_date + timedelta(days=additional_day_offset), local_time)