A CRM stores '10:30' beside a follow-up task. One representative reads it in Jaipur and another in London. Neither knows which timezone the value represents.
Time data needs to describe either an instant or a local scheduling intention. Those are different requirements.
Store instants unambiguously
An enquiry acceptance time is an instant. Store it using a timezone-aware database type or an explicit UTC representation supported by your system.
JavaScript can serialize a valid Date as a UTC ISO string:
const acceptedAt = new Date();
const timestamp = acceptedAt.toISOString();
This records the browser or server clock's value. For authoritative acceptance time, prefer the backend's timestamp and maintain its clock synchronization.
Do not infer an instant from an ambiguous string such as 06/07/2026 10:30.
Format for the reader
Display an instant in an explicit timezone using a locale-aware formatter:
const display = new Intl.DateTimeFormat("en-GB", {
dateStyle: "medium",
timeStyle: "short",
timeZone: "Asia/Kolkata"
}).format(acceptedAt);
Choose the display timezone from a documented user or application setting. Label it where confusion is possible.
Preserve scheduling intent
'Call tomorrow at 9 AM in the customer's timezone' contains more than an instant. Store the selected local date and time together with an IANA timezone identifier, then resolve it for execution.
Recurring local schedules need their timezone rules preserved. A fixed UTC offset does not represent future daylight-saving changes.
Some local times occur twice when clocks move backward; others do not occur when clocks move forward. Ask for or document a resolution policy rather than silently choosing an arbitrary instant.
Keep audit fields separate
| Field | Meaning |
|---|---|
| Accepted at | Backend accepted the enquiry |
| Event occurred at | Source reports when the event happened |
| Received at | Integration received the event |
| Next attempt at | Planned operational retry |
A delayed event's receipt time is not its occurrence time. Avoid overwriting one with another.
Test meaningful boundaries
Test different viewer timezones, month and year boundaries, daylight-saving transitions for relevant regions, invalid dates, and absent timezone settings.
The conversion code above is illustrative and should be verified in your target runtime. Consistent timestamps make routing, follow-ups, and incident investigation easier because everyone can identify which moment a record describes.
Top comments (1)
The distinction between an instant and a scheduling intention is the part I wish more write-ups made this clearly. Storing "call tomorrow at 9 AM in the customer's timezone" as a plain UTC timestamp quietly throws away the intent, and it only shows up months later when the clocks change. Keeping the audit fields separate — received at versus event occurred at versus next attempt at — is also a genuinely useful habit; I have seen delayed events overwrite the original time and then nobody can reconstruct what actually happened. The testing checklist at the end is a good reminder too, especially the DST transitions and month boundaries.