fix: support yearly recurrence in calendar
ci / docker (push) Successful in 5m34s

This commit is contained in:
2026-09-05 20:17:11 +08:00
parent 2e7c572af2
commit 05ab768a3b
2 changed files with 16 additions and 3 deletions
+8 -3
View File
@@ -64,8 +64,8 @@ def parse_rrule(value: str) -> dict[str, str]:
raise HTTPException(422, "无效的 RRULE")
key, val = part.split("=", 1)
parts[key] = val
if parts.get("FREQ") not in {"DAILY", "WEEKLY", "MONTHLY"}:
raise HTTPException(422, "仅支持 DAILY、WEEKLY、MONTHLY")
if parts.get("FREQ") not in {"DAILY", "WEEKLY", "MONTHLY", "YEARLY"}:
raise HTTPException(422, "仅支持 DAILY、WEEKLY、MONTHLY、YEARLY")
try:
if "INTERVAL" in parts and int(parts["INTERVAL"]) < 1:
raise ValueError
@@ -103,10 +103,15 @@ def occurrences(rule: str, starts: datetime, start: datetime, end: datetime, cut
elif parts["FREQ"] == "WEEKLY":
days = {_WEEKDAYS[x] for x in parts.get("BYDAY", list(_WEEKDAYS)[starts.weekday()]).split(",")}
include = cursor.weekday() in days and ((cursor.date() - starts.date()).days // 7) % interval == 0
else:
elif parts["FREQ"] == "MONTHLY":
month_delta = (cursor.year - starts.year) * 12 + cursor.month - starts.month
month_days = {int(x) for x in parts.get("BYMONTHDAY", str(starts.day)).split(",")}
include = month_delta % interval == 0 and cursor.day in month_days
else:
years = cursor.year - starts.year
months = {int(x) for x in parts.get("BYMONTH", str(starts.month)).split(",")}
month_days = {int(x) for x in parts.get("BYMONTHDAY", str(starts.day)).split(",")}
include = years % interval == 0 and cursor.month in months and cursor.day in month_days
if include and cursor >= starts:
emitted += 1
if start <= cursor <= end: