BBMM Technologies
← All articles
7 min readtime, timezones, engineering, correctness

Date, Time, and Timezone Handling Without Bugs

By Mykhailo Boichuk · Co-founder & Vice-President

In short

Most date and time bugs come from conflating an instant with a wall-clock time, or from storing a fixed offset instead of a timezone. Store instants in a single unambiguous representation, keep the timezone as a named region rather than an offset, convert only at the edges for display, and rely on a maintained timezone database. Daylight saving transitions create skipped and repeated local times that code must handle deliberately.

An instant is not a wall-clock time

The most consequential distinction in time handling is between an instant, a specific point on the universal timeline, and a wall-clock time, what a clock on a particular wall reads. A meeting at nine in the morning in Halifax and one in Vancouver are different instants despite sharing a wall-clock value. Treating the two as interchangeable is the root of a large fraction of time bugs.

The practical rule is to store and reason about instants internally, typically as a count from a fixed epoch in coordinated universal time, and to convert to a local wall-clock representation only when displaying to a person. Doing arithmetic on local times invites errors that an instant-based model avoids.

Store a timezone, not an offset

An offset such as minus four hours is a fact about a particular instant, not about a place. The same location has different offsets across the year because of daylight saving. Storing an offset and assuming it holds is a recurring bug. The correct unit is a named timezone region, which encodes the full set of rules and historical changes for that place.

  • Store timezones as named regions, not as fixed numeric offsets.
  • Derive the offset for a given instant from the region’s rules at that moment.
  • Keep the timezone database updated, since governments change rules with little notice.

Daylight saving creates real gaps

When clocks spring forward, an hour of local time does not exist, and a wall-clock value in that gap refers to no instant. When clocks fall back, an hour repeats, and a local value is ambiguous between two instants. Code that converts local times must decide what to do in both cases rather than assuming every local time maps to exactly one instant.

A scheduled reminder set for a local time that falls in a daylight-saving gap or repeat needs an explicit rule. Silently picking one interpretation produces reminders that fire at the wrong time or twice.

Convert at the edges, trust the library

The cleanest architecture keeps the core of the system working in instants and confines conversion to the boundaries where data enters from or is shown to a person. Within that boundary, use a well-maintained date and time library rather than hand-rolled arithmetic. Time rules are genuinely complicated, change without warning, and have been carefully encoded by people who track those changes. Reimplementing them is a reliable way to ship subtle bugs.

Key takeaways

  • Distinguish an instant on the timeline from a wall-clock local time.
  • Store and compute with instants; convert to local time only for display.
  • Store timezones as named regions, not fixed offsets, and keep the database updated.
  • Handle daylight-saving gaps and repeats with an explicit rule.
  • Use a maintained date and time library instead of hand-rolled arithmetic.

Frequently asked questions

Why is storing a UTC offset not enough?
An offset is a fact about a specific instant, and a place changes offset across the year due to daylight saving, so a named timezone region is the correct unit to store.
What goes wrong at daylight-saving transitions?
Springing forward skips an hour of local time that maps to no instant, and falling back repeats an hour that is ambiguous, so conversions need explicit rules for both.
Should I compute time arithmetic on local times?
No. Do arithmetic on instants and convert to local time only for display, using a maintained library rather than hand-rolled rules.

About the author

Mykhailo Boichuk

Co-founder & Vice-President

Mykhailo is an engineer who builds native applications and the systems behind them. He concentrates on macOS and iOS performance, local-first data architecture, and the synchronization problems that come with offline-capable software.