"""Пасхальное событие «Яички» (Блок 4: сезонность). По умолчанию окно — с 1 апреля по православную Пасху включительно (как было в исходном боте: 01.04–20.04.2025). Даты можно переопределить переменными ``EGG_EVENT_START``/``EGG_EVENT_END`` (например, для другого года или правила). """ from __future__ import annotations from datetime import date, datetime, timedelta from common.config import Settings #: Разница между юлианским и григорианским календарями для 1900–2099. _JULIAN_TO_GREGORIAN_DAYS = 13 def orthodox_easter(year: int) -> date: """Дата православной Пасхи (по юлианской пасхалии, переведённая в григорианский стиль).""" a = year % 4 b = year % 7 c = year % 19 d = (19 * c + 15) % 30 e = (2 * a + 4 * b - d + 34) % 7 month = (d + e + 114) // 31 day = ((d + e + 114) % 31) + 1 return date(year, month, day) + timedelta(days=_JULIAN_TO_GREGORIAN_DAYS) def egg_event_period(settings: Settings, today: date) -> tuple[date, date]: """Начало и конец окна «яичек» (включительно). Если в настройках заданы обе даты — берём их, иначе 1 апреля → православная Пасха года ``today``. """ if settings.egg_event_start and settings.egg_event_end: return settings.egg_event_start, settings.egg_event_end return date(today.year, 4, 1), orthodox_easter(today.year) def is_egg_event_active(settings: Settings, today: date | None = None) -> bool: """Идёт ли сейчас пасхальное событие (в таймзоне настроек).""" if today is None: today = datetime.now(settings.tzinfo).date() start, end = egg_event_period(settings, today) return start <= today <= end