Recurrence QA
Чеклист периодичности
Эта страница прогоняет движок расписания по всем поддержанным вариантам: день, неделя с несколькими днями, месяц, год, интервалы, завершение серии, поведение на выходных и работу в часовом поясе пользователя. Для каждого кейса ниже видно конфиг сущности, контрольный момент, ожидаемую следующую дату и фактический результат из кода.
| Статус | Кейс | Чеклист | Timezone | Контрольный момент | Ожидалось | Фактически | Следующие 5 запусков | Сущность |
|---|---|---|---|---|---|---|---|---|
| OK |
День: каждый день daily-default |
Базовое ежедневное повторение без интервала. | Europe/Moscow | 02.04.2026 10:00 | 03.04.2026 09:00 | 03.04.2026 09:00 |
|
{ "frequency": "daily", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": null, "start_date": "2026-04-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
День: каждые 3 дня daily-interval |
Проверка интервального daily режима. | Europe/Moscow | 05.04.2026 10:00 | 07.04.2026 09:00 | 07.04.2026 09:00 |
|
{ "frequency": "daily", "daily_every_n_days": 3, "daily_interval_unit": "days", "weekly": null, "monthly": null, "yearly": null, "start_date": "2026-04-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
День: каждые 3 месяца от даты старта daily-month-interval |
Daily режим с месячным интервалом из day-tab. | Europe/Moscow | 15.04.2026 10:00 | 10.07.2026 09:00 | 10.07.2026 09:00 |
|
{ "frequency": "daily", "daily_every_n_days": 3, "daily_interval_unit": "months", "weekly": null, "monthly": null, "yearly": null, "start_date": "2026-04-10", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Неделя: несколько дней weekly-multi-days |
Одна неделя, дни Пн/Ср/Пт. | Europe/Moscow | 07.04.2026 12:00 | 08.04.2026 09:00 | 08.04.2026 09:00 |
|
{ "frequency": "weekly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": { "everyNWeeks": 1, "weekDays": [ 1, 3, 5 ] }, "monthly": null, "yearly": null, "start_date": "2026-04-06", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Неделя: каждые 2 недели по Вт и Чт weekly-interval |
Проверка недельного интервала и нескольких дней. | Europe/Moscow | 16.04.2026 10:00 | 21.04.2026 09:00 | 21.04.2026 09:00 |
|
{ "frequency": "weekly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": { "everyNWeeks": 2, "weekDays": [ 2, 4 ] }, "monthly": null, "yearly": null, "start_date": "2026-04-07", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Месяц: 15 числа monthly-day |
Фиксированный день месяца. | Europe/Moscow | 16.04.2026 00:00 | 15.05.2026 09:00 | 15.05.2026 09:00 |
|
{ "frequency": "monthly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": { "mode": "dayOfMonth", "dayOfMonth": 15, "everyNMonths": 1 }, "yearly": null, "start_date": "2026-01-15", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Месяц: 31 число с зажимом на конец месяца monthly-day-clamped |
Короткий месяц должен дать последнее число. | Europe/Moscow | 01.02.2026 00:00 | 28.02.2026 09:00 | 28.02.2026 09:00 |
|
{ "frequency": "monthly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": { "mode": "dayOfMonth", "dayOfMonth": 31, "everyNMonths": 1 }, "yearly": null, "start_date": "2026-01-31", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Месяц: второй четверг monthly-nth-weekday |
Nth weekday внутри месяца. | Europe/Moscow | 15.01.2026 00:00 | 12.02.2026 09:00 | 12.02.2026 09:00 |
|
{ "frequency": "monthly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": { "mode": "nthWeekday", "weekNumber": 2, "weekDay": 4, "everyNMonths": 1 }, "yearly": null, "start_date": "2026-01-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Месяц: второй четверг каждые 2 месяца monthly-nth-weekday-interval |
Nth weekday c месячным интервалом. | Europe/Moscow | 15.01.2026 00:00 | 12.03.2026 09:00 | 12.03.2026 09:00 |
|
{ "frequency": "monthly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": { "mode": "nthWeekday", "weekNumber": 2, "weekDay": 4, "everyNMonths": 2 }, "yearly": null, "start_date": "2026-01-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Год: фиксированная дата yearly-fixed-date |
Повторение каждый год по одной дате. | Europe/Moscow | 11.03.2026 00:00 | 10.03.2027 09:00 | 10.03.2027 09:00 |
|
{ "frequency": "yearly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": { "mode": "fixedDate", "month": 3, "day": 10, "everyNYears": 1 }, "start_date": "2026-01-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Год: фиксированная дата каждые 2 года yearly-fixed-date-interval |
Годовой интервал для fixed date. | Europe/Moscow | 11.03.2026 00:00 | 10.03.2028 09:00 | 10.03.2028 09:00 |
|
{ "frequency": "yearly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": { "mode": "fixedDate", "month": 3, "day": 10, "everyNYears": 2 }, "start_date": "2026-01-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Год: второй четверг апреля yearly-nth-weekday |
Nth weekday of month внутри года. | Europe/Moscow | 10.04.2026 00:00 | 08.04.2027 09:00 | 08.04.2027 09:00 |
|
{ "frequency": "yearly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": { "mode": "nthWeekdayOfMonth", "weekNumber": 2, "weekDay": 4, "nthMonth": 4, "everyNYears": 1 }, "start_date": "2026-01-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Год: второй четверг апреля каждые 2 года yearly-nth-weekday-interval |
Nth weekday of month с годовым интервалом. | Europe/Moscow | 10.04.2026 00:00 | 13.04.2028 09:00 | 13.04.2028 09:00 |
|
{ "frequency": "yearly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": { "mode": "nthWeekdayOfMonth", "weekNumber": 2, "weekDay": 4, "nthMonth": 4, "everyNYears": 2 }, "start_date": "2026-01-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Завершение: после N повторений end-by-count |
Серия должна закончиться и next должен стать пустым. | Europe/Moscow | 10.04.2026 00:00 | Нет следующего запуска | Нет следующего запуска |
|
{ "frequency": "daily", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": null, "start_date": "2026-04-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "byCount", "end_date": null, "occurrence_count": 3, "non_working_day_mode": "createAnyway" } |
| OK |
Завершение: по дате end-by-date |
После endDate next occurrence отсутствует. | Europe/Moscow | 10.04.2026 00:00 | Нет следующего запуска | Нет следующего запуска |
|
{ "frequency": "daily", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": null, "start_date": "2026-04-01", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "byDate", "end_date": "2026-04-04", "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Выходные: создать задачу как есть non-working-create |
Суббота остается субботой. | Europe/Moscow | 10.04.2026 00:00 | 11.04.2026 09:00 | 11.04.2026 09:00 |
|
{ "frequency": "weekly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": { "everyNWeeks": 1, "weekDays": [ 6 ] }, "monthly": null, "yearly": null, "start_date": "2026-04-11", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |
| OK |
Выходные: перенос на рабочий день non-working-shift |
Субботняя задача должна сдвинуться на понедельник. | Europe/Moscow | 10.04.2026 00:00 | 13.04.2026 09:00 | 13.04.2026 09:00 |
|
{ "frequency": "weekly", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": { "everyNWeeks": 1, "weekDays": [ 6 ] }, "monthly": null, "yearly": null, "start_date": "2026-04-11", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "shiftToNextWorkday" } |
| OK |
Выходные: пропуск non-working-skip |
Рабочий день остается рабочим, а ближайшие выходные пропускаются. | Europe/Moscow | 10.04.2026 00:00 | 10.04.2026 09:00 | 10.04.2026 09:00 |
|
{ "frequency": "daily", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": null, "start_date": "2026-04-10", "create_time": "09:00", "timezone": "Europe\/Moscow", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "skip" } |
| OK |
Часовой пояс пользователя timezone-user |
План в Asia/Yekaterinburg должен считать 09:00 именно в этом timezone. | Asia/Yekaterinburg | 01.04.2026 08:00 | 01.04.2026 09:00 | 01.04.2026 09:00 |
|
{ "frequency": "daily", "daily_every_n_days": 1, "daily_interval_unit": null, "weekly": null, "monthly": null, "yearly": null, "start_date": "2026-04-01", "create_time": "09:00", "timezone": "Asia\/Yekaterinburg", "end_mode": "none", "end_date": null, "occurrence_count": null, "non_working_day_mode": "createAnyway" } |