Skip to content
FeaturesPricingAffiliateBlogHelpAboutContact
Get StartedSign In
Back to Blog
industry2026-05-2311 min read

My daily goal said 95% at 4 PM but the register showed 112% — JavaScript setHours shifted my UTC+3 operator's goal window by 3 hours

Aylin (34), bistro owner in Istanbul Kadıköy, sees the dashboard at 16:00 Tuesday show "95% → ₺2,375" but the cash register cumulative is ₺2,806 (112%). 17 percentage point gap — she'd been making evening service decisions based on the panel for six months. Forensic: `apps/web-admin/src/app/[locale]/dashboard/goals/GoalsClient.tsx:53-63` called `start.setHours(0,0,0,0).toISOString()` — `setHours` is LOCAL TZ, for UTC+3 Aylin that's "today 00:00 Istanbul" = "yesterday 21:00 UTC", and `.toISOString()` serialized to that UTC offset → server's UTC filter saw `starts_at: yesterday 21:00 UTC` → panel covered a UTC day but operator's mental model expected an Istanbul day → ~12% misattribution (evening service that crosses midnight Istanbul falls into yesterday's panel). **PR #651 batch VII F3** fix: `setUTCHours(0,0,0,0)` + `setUTCDate/getUTCMonth` variants. Client now writes UTC-aligned boundary; math is consistent. Per-restaurant TZ (`restaurant.timezone` IANA TZ database) is the full fix — operator sees "their day" — earmarked for follow-up larger refactor. Pattern: JavaScript Date API has 18 LOCAL + 18 parallel UTC methods; every boundary flowing to a UTC-canonical SQL filter MUST use UTC variants.

th

thMenu Team

thmenu.com

Found this helpful? Share it.