Fix multi-day events showing on all days they span

- Fetch from 7 days back so events that started before today (e.g.
  weekly chore rotation starting last Sunday) are included
- All-day multi-day events now appear on every day they cover, not just
  their start date (using iCal's exclusive-end convention correctly)
- Timed events continue to show only on their start date

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 17:08:33 +12:00
parent 41e9c3bf71
commit 575eb6c525

21
app.py
View File

@@ -185,9 +185,11 @@ def get_calendar():
cal = Calendar.from_ical(response.content)
range_start = nz_tz.localize(datetime.combine(start_date, datetime.min.time()))
range_end = range_start + timedelta(days=NUM_DAYS)
recurring_events = recurring_ical_events.of(cal).between(range_start, range_end)
# Fetch from 7 days back so multi-day events that started before
# today (e.g. "Bins - Daniel's Week" starting last Sunday) are included.
fetch_start = nz_tz.localize(datetime.combine(start_date - timedelta(days=7), datetime.min.time()))
fetch_end = nz_tz.localize(datetime.combine(start_date + timedelta(days=NUM_DAYS), datetime.min.time()))
recurring_events = recurring_ical_events.of(cal).between(fetch_start, fetch_end)
events = []
for component in recurring_events:
@@ -233,10 +235,21 @@ def get_calendar():
events.sort(key=lambda x: x['start'])
def event_covers_day(e, d):
e_start = datetime.fromisoformat(e['start'])
e_end = datetime.fromisoformat(e['end'])
is_all_day = (e_start.hour == 0 and e_start.minute == 0 and
e_end.hour == 0 and e_end.minute == 0)
if is_all_day:
# iCal all-day end is exclusive (end = day after last day)
return e_start.date() <= d < e_end.date()
else:
return e_start.date() == d
days = []
for i in range(NUM_DAYS):
d = start_date + timedelta(days=i)
day_events = [e for e in events if datetime.fromisoformat(e['start']).date() == d]
day_events = [e for e in events if event_covers_day(e, d)]
days.append({'date': d.isoformat(), 'weekday': d.strftime('%A'), 'events': day_events})
result = {