From 7677ab4028fca416bbc966b651b901a8df441bdf Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sat, 4 Apr 2026 11:01:51 -0400 Subject: [PATCH] fix(calendar): use date-only strings for all-day events to prevent timezone shift UTC midnight passed to FullCalendar's timeZone:'local' was being converted to local time, shifting all-day events back by 1+ days for users in UTC-X zones. The edit form had the same bug via new Date(). Fix: pass YYYY-MM-DD slices (UTC date) for all-day events in both toFcEvent and EventSlideOver resetForm, bypassing timezone conversion. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/components/EventSlideOver.vue | 6 ++++-- frontend/src/views/CalendarView.vue | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/EventSlideOver.vue b/frontend/src/components/EventSlideOver.vue index 5c5a776..0eb2c39 100644 --- a/frontend/src/components/EventSlideOver.vue +++ b/frontend/src/components/EventSlideOver.vue @@ -68,9 +68,11 @@ function resetForm() { if (props.event) { title.value = props.event.title; allDay.value = props.event.all_day; - startDate.value = dateFromIso(props.event.start_dt); + // All-day events: use UTC date string directly to avoid timezone shifting + // (UTC midnight parsed through new Date() becomes the previous day in UTC-X zones) + startDate.value = props.event.all_day ? props.event.start_dt.slice(0, 10) : dateFromIso(props.event.start_dt); startTime.value = props.event.all_day ? "" : timeFromIso(props.event.start_dt); - endDate.value = props.event.end_dt ? dateFromIso(props.event.end_dt) : ""; + endDate.value = props.event.end_dt ? (props.event.all_day ? props.event.end_dt.slice(0, 10) : dateFromIso(props.event.end_dt)) : ""; endTime.value = props.event.end_dt && !props.event.all_day ? timeFromIso(props.event.end_dt) : ""; description.value = props.event.description || ""; location.value = props.event.location || ""; diff --git a/frontend/src/views/CalendarView.vue b/frontend/src/views/CalendarView.vue index a6ac12e..590ac3f 100644 --- a/frontend/src/views/CalendarView.vue +++ b/frontend/src/views/CalendarView.vue @@ -39,11 +39,13 @@ function closeSlideOver() { const eventCache = new Map(); function toFcEvent(e: EventEntry) { + // For all-day events pass date-only strings so FullCalendar never shifts + // the date through timezone conversion (UTC midnight → previous day in UTC-X). return { id: String(e.id), title: e.title, - start: e.start_dt, - end: e.end_dt ?? undefined, + start: e.all_day ? e.start_dt.slice(0, 10) : e.start_dt, + end: e.all_day ? (e.end_dt?.slice(0, 10) ?? undefined) : (e.end_dt ?? undefined), allDay: e.all_day, backgroundColor: e.color || undefined, borderColor: e.color || undefined,