Timestamp Bugs: Seconds, Milliseconds, and Time Zones
A practical checklist for debugging timestamp bugs across Unix seconds, milliseconds, ISO strings, time zones, date-only values, and schedules.

Timestamp bugs are easy to misread because the data often looks valid. A number parses. An ISO string renders. A scheduled job runs. The problem shows up later as an off-by-one day, a notification sent at the wrong hour, or an API record that appears to be created in the future.
The fix is not to memorize every date library edge case. The fix is to debug time values in a repeatable order: identify the unit, name the time zone, preserve the raw value, and compare the displayed result against the intended moment.
Start With the Source of Truth
Before changing code, decide which value is supposed to be authoritative. It might be a database column, an API response, a queue payload, a browser input, or a third-party webhook. If two systems disagree, the source of truth tells you which side needs conversion.
For most product events, store an instant in UTC and convert only at the edges. For human calendar concepts like birthdays, billing dates, holidays, and local business hours, treat the date and the time zone as part of the domain model rather than decoration.
Confirm Seconds vs Milliseconds
The most common timestamp bug is a unit mismatch. Unix seconds and Unix milliseconds are both numbers, but they differ by a factor of 1000. JavaScript Date constructors expect milliseconds, while many APIs, logs, and auth claims use seconds.
- A 10-digit Unix timestamp is usually seconds.
- A 13-digit Unix timestamp is usually milliseconds.
- JWT exp and iat claims are commonly Unix seconds.
- Browser Date.now() returns Unix milliseconds.
- Database timestamps and JSON APIs may use ISO strings instead of numeric Unix time.
When a date lands around 1970, far in the future, or thousands of years away, check the unit before checking business logic.
Name the Time Zone Explicitly
A timestamp without a time zone rule is a trap. UTC is a time standard. A local time zone is a business decision. A browser, server, database, and user can all have different local defaults.
- Record whether incoming data is UTC, local time, or offset-based.
- Avoid relying on server local time for scheduled work.
- Log the time zone used for user-facing conversion.
- Store offsets only when the offset itself is meaningful; store named zones when future local scheduling matters.
The difference matters because offsets can change with daylight saving rules, but named zones preserve the rule set needed to calculate future local times.
Treat Date-Only Values Differently
A date-only value is not the same thing as midnight UTC. Values like YYYY-MM-DD often represent a calendar day, not a precise instant. If you convert that value into an instant too early, users in some time zones may see the previous or next day.
This shows up in forms, birthdays, due dates, reports, and subscription periods. Keep date-only values as dates when the business meaning is a day. Convert to a timestamp only when you know the exact boundary and time zone.
Check Boundaries Before the Middle
Most date bugs hide at boundaries: start of day, end of day, month end, year end, daylight saving transitions, leap years, and inclusive or exclusive filters. A query that works at noon can fail at midnight.
- Use half-open ranges when filtering intervals: start inclusive, end exclusive.
- Define whether end dates include the full final day.
- Test month boundaries with short and long months.
- Test daylight saving changes in zones your users actually use.
- Compare scheduled job time in UTC and the intended local zone.
Compare Raw and Rendered Values
When a display looks wrong, keep both values visible: the raw timestamp and the rendered local date. Add the time zone, offset, browser locale, server environment, and library formatting call. A formatted date alone hides the conversion path.
The Timestamp Converter is useful for this step because it lets you check Unix seconds, Unix milliseconds, and readable dates side by side before editing application code.
Timestamp Debugging Checklist
- Identify the source of truth before changing conversions.
- Check whether the value is Unix seconds, Unix milliseconds, or an ISO string.
- Confirm the input time zone and the output time zone.
- Keep date-only values separate from exact instants.
- Test start and end boundaries, not only typical midday examples.
- Check daylight saving behavior for relevant named zones.
- Log raw values next to rendered values during debugging.
- Use one canonical storage format and convert at system edges.
Time bugs become manageable when every value has a unit, a zone, and a purpose. Once those three facts are visible, most timestamp failures stop looking mysterious and start looking mechanical.
Related Posts

Color Palettes: Check Contrast Before the UI Ships
Build palettes that hold up in real interfaces by checking contrast, states, tokens, and light/dark backgrounds before CSS changes ship.

UUIDs: Pick Identifiers That Survive Real Systems
Use UUIDs deliberately: choose the right identifier shape, keep IDs opaque, avoid collisions, and test how values move through APIs and databases.

Password Generators: Create Strong Secrets Without Leaks
Generate passwords safely by choosing length, randomness, and storage habits before a secret ever leaves your browser.