Converting API Timestamps to the User's Local Time Instead of Hardcoding Dubai Time
TIL that hardcoding a UTC+4 offset for timestamps because most orders happened to be local worked right up until a driver or a server ended up in a different timezone.
The Problem #
"Delivered at 2:00 PM" displayed correctly for months, because the API stored UTC timestamps and the frontend converted them by adding a hardcoded 4-hour offset — which happens to be correct for Dubai and nowhere else.
Context #
Every early tester and every deployment target was in the same timezone, so the hardcoded offset never got exercised against a different one, and there was nothing forcing the assumption to surface.
What I Tried #
Nothing, initially — it wasn't a bug I went looking for. It surfaced when a dashboard was opened by someone in a different timezone and the delivery times were visibly off by hours.
What Went Wrong #
new Date(timestamp).getHours() + 4 isn't a timezone conversion, it's a fixed arithmetic offset that happens to match one specific timezone with no daylight saving complications. It breaks the moment the viewer, not just the delivery, is somewhere else.
The Solution #
Stopped doing manual offset math and used the browser's own timezone-aware formatting, which reads the viewing device's timezone rather than assuming one.
new Date(isoTimestamp).toLocaleTimeString(undefined, {
hour: "numeric",
minute: "2-digit",
});
// undefined locale + no explicit timeZone = "use the browser's own settings"Why It Works #
Intl-backed formatting (which toLocaleString/toLocaleTimeString use under the hood) reads the actual system timezone database, not a hardcoded assumption — it's correct for a viewer in Dubai, Manila, or anywhere else, and it correctly handles daylight saving where relevant, which manual offset arithmetic never does.
Lessons Learned #
Code that's only ever tested from one timezone can hide a timezone bug indefinitely — "it's always been correct" isn't evidence the logic is right, it's evidence the assumption hasn't been tested yet.
What I Would Do Differently #
I'd store and transmit timestamps in UTC (which was already happening) and format them with locale-aware Intl calls from the very first display, rather than reaching for what looked like simpler arithmetic.
Related Concepts #
UTC vs. local time storage, the Intl API, daylight saving time edge cases.
Related content
Using Framer Alongside a Development Workflow, Not Instead of One
TIL that building the Clonify Framer plugin taught me Framer is a genuinely different target than a normal web build — its plugin runtime and code-component model don't map 1:1 onto React conventions.
Designing a Dispatch Management Dashboard for Real Operations, Not a Generic Admin Panel
TIL that a dispatch dashboard built around 'show all the order fields' overwhelmed the person actually using it — the redesign that worked started from what a dispatcher needs to decide, not what data exists.
Serving Premium Downloads Without Exposing the File's Real Storage URL
TIL how to replace a guessable direct-download link with a permission-checked, time-limited presigned URL, so the object storage path a purchased asset actually lives at is never sent to the client.