checklistdatestimezonesdsttestingqa

A Checklist for Testing Dates, Time and Time Zones

Dates and time are one of those areas that look simple and break in sneaky ways: the bug doesn’t show up right away — it surfaces six months later, on the night the clocks change, on February 29, or for a user in another time zone. Here’s a practical checklist of what to test.

Storage and model

  • Everything on the backend is UTC. The time zone is applied only for display. Storing local time without a zone is an almost guaranteed bug.
  • “Naive” datetimes (no tz) are a red flag: when compared, sorted, or written to the DB they get silently interpreted differently.
  • Separate a point in time from a calendar date. A “date of birth” and a “deadline at 23:59” are different things: one has no time/zone, the other does.
  • Check that the API returns time in ISO 8601 with an offset (2026-08-18T14:30:00Z or +02:00), not an ambiguous local form.

Time zones

  • User in one TZ, server in another, data created in a third — test the whole chain.
  • User changed time zone (flight, VPN, manual change in settings) — past events must not “shift”.
  • Offsets aren’t always whole hours: India (+05:30), Nepal (+05:45), parts of Australia.
  • Are you using an up-to-date time zone database (IANA/tzdata)? Countries change their rules; hardcoding an offset is a bug.

Daylight saving (DST)

  • Non-existent time: springing forward skips an hour (e.g., 02:00→03:00). What does the system do with an event at 02:30?
  • Duplicated time: falling back, 02:30 happens twice. Which of the two moments is meant?
  • An event in the transition “gap” — a reminder/cron/booking exactly on the missing hour.
  • Countries switch DST on different dates (and not all switch at all) — don’t hardcode “like in the US/EU”.

Display and input formats

  • 04/05/2026 — is that May 4 or April 5? Check DD/MM vs MM/DD by locale, for output and input.
  • 12h vs 24h, AM/PM, midnight 00:00 vs 12:00 AM, noon.
  • Local separators and order; month/day names in the user’s language.
  • First day of the week (Mon or Sun — locale-dependent) in date pickers.

Boundaries (where it all breaks)

  • Midnight and crossing midnight; events exactly at 00:00 and 23:59:59.
  • End of month/year; the “31st” in months that don’t have one.
  • February 29 (leap year) — and “+1 year” from Feb 29.
  • “+1 month” from January 31 — Feb 28/29 or March 3? Pin down the expected behavior.
  • Epoch and overflow: Unix time 0 (1970), the year 2038 problem (32-bit time_t), very large/negative dates.

Calculations and differences

  • The difference between dates across a DST transition — a day may not be 24 hours (23 or 25).
  • Age, “days remaining”, business days (excluding weekends/holidays by country).
  • Adding durations: “in 90 days” vs “in 3 months” — these are different results.
  • Comparing times from different zones — normalize to a single moment (UTC), don’t compare them “as is”.

Relative time

  • “5 minutes ago”, “tomorrow”, “in 2 hours” — test at boundaries (23:59 → “tomorrow”).
  • The client’s clock is wrong/skewed — don’t trust the device time for critical logic (tokens, deadlines); the source of truth is the server.
  • Live-updating relative labels (after a minute, “just now” should become “1 min ago”).

How to reproduce

  • Change the device/OS time zone and language — the fastest way to catch display bugs.
  • Freeze/mock the clock in automated tests (pin “now”), otherwise the test flakes near midnight/year boundary.
  • Keep a set of dangerous dates as test data: Feb 29, DST-change night (forward and back), Dec 31 23:59, a +05:45 zone, the year 2038.
  • Run in at least two or three time zones (UTC, one with DST, one with a half-hour offset).

In short

  • Store in UTC, apply the zone only for display; “naive” datetimes are a bug.
  • DST creates non-existent and duplicated time — test events in those windows.
  • Date formats are ambiguous (04/05) — test output and input by locale.
  • Boundaries: midnight, end of month, Feb 29, “+1 month” from the 31st, 2038.
  • Don’t trust the client’s clock; the server is the source of time.
  • Reproduce by changing the device TZ + freezing the clock + a set of dangerous dates.