Few bugs are as embarrassing as a booking that shows the wrong day, an invoice dated tomorrow, or a report that is off by one because a user lives in a different time zone. Dates and times look simple, yet they are one of the most reliable sources of defects in web and mobile apps, especially once your product leaves a single city or country.
If you are building a SaaS product, a booking platform, or any app that serves users across India, the Gulf, Australia, and the US, getting time handling right early is far cheaper than fixing it after launch. This guide covers the rules we follow at Mavani Solution, the traps that catch most teams, and a practical process you can apply to your own codebase. It pairs well with our guide on multi-currency pricing for global SaaS expansion, since money and time zones tend to go wrong together.
A timestamp is not just a number. It is a number plus an interpretation, and that interpretation depends on a time zone, a calendar, a daylight saving rule, and sometimes a political decision. Governments change daylight saving rules with little notice. Some regions shift by 30 or 45 minutes rather than whole hours. India uses a single zone without daylight saving, while the US and Australia each span several zones and switch clocks on different dates.
Developers also mix up three different concepts that deserve separate treatment:
Most bugs come from storing one of these as if it were another.
Whenever you record when something happened, store it as a UTC timestamp (or an ISO 8601 string with an explicit offset). Convert to a local time zone only at the edge, when displaying to a person. This keeps sorting, comparisons, and calculations consistent.
An offset such as +05:30 tells you how far a time is from UTC at one moment. It does not tell you what happens next month. For anything in the future, like a recurring appointment, store the IANA zone name (for example Asia/Kolkata or Australia/Sydney) so daylight saving transitions are handled correctly.
A birthday, a billing date, or a public holiday should be saved as a plain date. If you store it as midnight UTC and then display it in a zone behind UTC, it will appear as the previous day. This single mistake accounts for a large share of "off by one day" support tickets.
Adding 24 hours is not the same as adding one day when a daylight saving change happens in between. Use a proper date library and do calendar arithmetic in the correct zone.
Here is an illustrative scenario. A clinic booking app launched in Gujarat with all times saved as local strings like "2026-03-10 17:00". It worked perfectly until the founders added tele-consultations for patients in Australia and the UAE. Patients began joining calls an hour early or late, reminders arrived at 3 AM, and a doctor's "recurring Tuesday 5 PM" slot drifted after a daylight saving change in a patient's region.
The fix was not clever. The team stored appointment start times as UTC instants, saved the clinic's IANA zone on each doctor profile, recorded the patient's zone on each booking, and generated recurring slots by applying the doctor's zone rules for each occurrence rather than adding fixed intervals. Reminders were scheduled from the UTC instant and rendered in the recipient's zone. This is a composite example meant to illustrate typical failures, not a specific reported client result.
If your product has bookings at its core, you may also want to read our guide to building an appointment booking system for service businesses.
Phones and laptops can have wrong times or manually changed zones. For anything security-sensitive or financial, such as token expiry or payment timestamps, rely on server time. Use client time only for display and convenience.
The string "03/04/2026" means 3 April in India and 4 March in the US. Always exchange dates in ISO 8601 format (2026-04-03) between systems, and only localise when rendering to a human.
On daylight saving transition days, a local day can be 23 or 25 hours long. Reports that group by day should group using the business's local zone, not by slicing UTC into 24-hour blocks.
In a system with several services, one may emit local times while another expects UTC. Document the contract in your API schema, and have every endpoint return explicit offsets or UTC markers. If your team is working through service boundaries, our write-up on API versioning and backward compatibility for mobile apps explains how to change contracts safely.
You do not need to build any of this from scratch. Modern JavaScript is getting a built-in Temporal API that models instants, zoned date-times, and plain dates as separate types, which matches the mental model above. Until it is available everywhere you target, mature libraries such as date-fns with time zone support, Luxon, or Day.js with its time zone plugin can do the heavy lifting. On the backend, most languages ship with a standard library or a trusted package for IANA zones. In your database, prefer native timestamp-with-time-zone types over strings.
Also keep your time zone database up to date. The IANA tz database changes several times a year as governments adjust rules. Container images, operating systems, and mobile runtimes all carry their own copy, so include tz data updates in your regular dependency maintenance. Missing an update rarely breaks things loudly. It just makes some users' times quietly wrong for a few weeks.
If your product already has years of data stored as local strings, migrating can feel risky. The safe path is to add new, correctly typed columns, backfill them using the best-known zone for each record, run both in parallel while you compare outputs, and then retire the old fields. Plan for edge cases where the original zone cannot be known, and decide a documented default for them.
Teams building products for international users often find that time handling is just one of several foundations worth reviewing together, alongside payments, localisation, and data residency. Our web development services include architecture reviews that catch these issues before they reach customers.
Time bugs feel random, but they follow a small number of patterns. Store instants in UTC, store IANA zones for anything in the future, keep calendar dates separate from timestamps, centralise formatting, and test the awkward days. None of this is glamorous work, yet it protects the trust users place in your product every time they book, pay, or schedule something.
If you are planning to serve customers across regions, make time handling an explicit part of your design from the first sprint. It costs little at the start and saves a great deal later. And if you already have a live product with strange date behaviour, an audit following the steps above will usually reveal the cause within a day or two.