From d4056404b6abbde9e2b3fd61caa87fd343b3bf4a Mon Sep 17 00:00:00 2001 From: cavidelizade Date: Fri, 17 Jul 2026 00:50:56 +0400 Subject: [PATCH] fix(ui): stop Gantt dates shifting a day for clients behind UTC parseDay ran the date through Date.parse then read local components off the resulting UTC instant, so "2026-07-16" landed on the 15th in any negative-UTC timezone. Bars rendered a day early and a visible one-day drag re-serialized to the same stored date, making the move a no-op. Parse the leading YYYY-MM-DD parts into a local-midnight date instead, the same way the calendar layout does. Closes #337 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../components/work-item/layouts/IssueLayoutGantt.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsx b/apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsx index 580eb51..3066aff 100644 --- a/apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsx +++ b/apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsx @@ -420,9 +420,14 @@ function startOfDay(d: Date): Date { } function parseDay(input: string): number | null { - const t = Date.parse(input); - if (Number.isNaN(t)) return null; - return startOfDay(new Date(t)).getTime(); + // Dates arrive as "YYYY-MM-DD" or a UTC-midnight ISO timestamp. Take the + // leading date parts and build a local-midnight date, so the day doesn't + // shift for clients behind UTC. Routing the value through Date.parse + + // new Date reads local components off a UTC instant and lands on the previous + // day in the Americas (the calendar layout avoids this the same way). + const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(input); + if (!m) return null; + return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3])).getTime(); } function pad2(n: number): string {