Find next delta. Takes a :class:`~datetime.datetime` of last run, next minute and hour, and returns a :class:`~celery.utils.time.ffwd` for the next scheduled day and time. Only called when ``day_of_month`` and/or ``month_of_year`` cronspec is specified to fu
(self, last_run_at: datetime, next_hour: int,
next_minute: int)
| 478 | return result |
| 479 | |
| 480 | def _delta_to_next(self, last_run_at: datetime, next_hour: int, |
| 481 | next_minute: int) -> ffwd: |
| 482 | """Find next delta. |
| 483 | |
| 484 | Takes a :class:`~datetime.datetime` of last run, next minute and hour, |
| 485 | and returns a :class:`~celery.utils.time.ffwd` for the next |
| 486 | scheduled day and time. |
| 487 | |
| 488 | Only called when ``day_of_month`` and/or ``month_of_year`` |
| 489 | cronspec is specified to further limit scheduled task execution. |
| 490 | """ |
| 491 | datedata = AttributeDict(year=last_run_at.year) |
| 492 | days_of_month = sorted(self.day_of_month) |
| 493 | months_of_year = sorted(self.month_of_year) |
| 494 | |
| 495 | def day_out_of_range(year: int, month: int, day: int) -> bool: |
| 496 | try: |
| 497 | datetime(year=year, month=month, day=day) |
| 498 | except ValueError: |
| 499 | return True |
| 500 | return False |
| 501 | |
| 502 | def is_before_last_run(year: int, month: int, day: int) -> bool: |
| 503 | return self.maybe_make_aware( |
| 504 | datetime(year, month, day, next_hour, next_minute), |
| 505 | naive_as_utc=False) < last_run_at |
| 506 | |
| 507 | def roll_over() -> None: |
| 508 | for _ in range(2000): |
| 509 | flag = (datedata.dom == len(days_of_month) or |
| 510 | day_out_of_range(datedata.year, |
| 511 | months_of_year[datedata.moy], |
| 512 | days_of_month[datedata.dom]) or |
| 513 | (is_before_last_run(datedata.year, |
| 514 | months_of_year[datedata.moy], |
| 515 | days_of_month[datedata.dom]))) |
| 516 | |
| 517 | if flag: |
| 518 | datedata.dom = 0 |
| 519 | datedata.moy += 1 |
| 520 | if datedata.moy == len(months_of_year): |
| 521 | datedata.moy = 0 |
| 522 | datedata.year += 1 |
| 523 | else: |
| 524 | break |
| 525 | else: |
| 526 | # Tried 2000 times, we're most likely in an infinite loop |
| 527 | raise RuntimeError('unable to rollover, ' |
| 528 | 'time specification is probably invalid') |
| 529 | |
| 530 | if last_run_at.month in self.month_of_year: |
| 531 | datedata.dom = bisect(days_of_month, last_run_at.day) |
| 532 | datedata.moy = bisect_left(months_of_year, last_run_at.month) |
| 533 | else: |
| 534 | datedata.dom = 0 |
| 535 | datedata.moy = bisect(months_of_year, last_run_at.month) |
| 536 | if datedata.moy == len(months_of_year): |
| 537 | datedata.moy = 0 |
no test coverage detected