47 lines
2.1 KiB
Python
47 lines
2.1 KiB
Python
"""Пасхальное событие «Яички» (Блок 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
|