From 353de06d8be94262a81a3553a868b383dc75a39d Mon Sep 17 00:00:00 2001 From: Dom Carroll Date: Thu, 29 Jan 2026 14:16:06 +1000 Subject: [PATCH] fix: Calendar timezone day-shift bug (#7048) Events scheduled for today were appearing in tomorrow's column due to raw millisecond arithmetic not handling timezone transitions properly. Changes: - Replace MILLISECONDS_IN_DAY * day arithmetic with Date.setDate() - Fix mutation bug where date parameter was being modified - Use proper calendar day arithmetic that handles DST/timezone Tested in Brisbane timezone (GMT+10) - events now display in correct column. Co-Authored-By: Claude Opus 4.5 Signed-off-by: Dominic O'Carroll <99632940+domocarroll@users.noreply.github.com> --- .../src/components/DayCalendar.svelte | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/plugins/calendar-resources/src/components/DayCalendar.svelte b/plugins/calendar-resources/src/components/DayCalendar.svelte index eb5bc05fd28..5f821af4aea 100644 --- a/plugins/calendar-resources/src/components/DayCalendar.svelte +++ b/plugins/calendar-resources/src/components/DayCalendar.svelte @@ -106,9 +106,12 @@ ): CalendarItem[] => { const result: CalendarItem[] = [] for (let day = 0; day < days; day++) { - const startDay = new Date(MILLISECONDS_IN_DAY * day + date.getTime()).setHours(0, 0, 0, 0) - const startDate = new Date(MILLISECONDS_IN_DAY * day + date.getTime()).setHours(startHour, 0, 0, 0) - const lastDate = new Date(MILLISECONDS_IN_DAY * day + date.getTime()).setHours(endHour, 0, 0, 0) + // Use setDate() for proper day arithmetic that handles timezone transitions + const targetDay = new Date(date) + targetDay.setDate(targetDay.getDate() + day) + const startDay = new Date(targetDay).setHours(0, 0, 0, 0) + const startDate = new Date(targetDay).setHours(startHour, 0, 0, 0) + const lastDate = new Date(targetDay).setHours(endHour, 0, 0, 0) events.forEach((event) => { const eventStart = event.allDay ? event.date + offsetTZ : event.date const eventEnd = event.allDay ? event.dueDate + offsetTZ : event.dueDate @@ -125,8 +128,11 @@ } }) } - const sd = date.setHours(0, 0, 0, 0) - const ld = new Date(MILLISECONDS_IN_DAY * (days - 1) + date.getTime()).setHours(23, 59, 59, 999) + // Fix: Don't mutate the date parameter, use setDate() for proper day arithmetic + const sd = new Date(date).setHours(0, 0, 0, 0) + const lastDayDate = new Date(date) + lastDayDate.setDate(lastDayDate.getDate() + days - 1) + const ld = new Date(lastDayDate).setHours(23, 59, 59, 999) events .filter((ev) => ev.allDay) .sort((a, b) => b.dueDate - b.date - (a.dueDate - a.date))