← Back to the tool

Unix Timestamps and Timezones

Updated: May 2026

A Unix timestamp has no timezone — it is an absolute count of seconds from the UTC epoch. And yet timezone bugs involving timestamps are among the most common defects in production software. The bugs live entirely in the conversion layer: when timestamps are created from local strings or displayed without an explicit timezone.

Convert timestamp with timezone →

Free · No upload · Instant

The fundamental principle

A Unix timestamp is always UTC. The integer 1735689600 represents exactly one moment in history: January 1, 2025, 00:00:00 UTC. This moment corresponds to different local times depending on where you are: 19:00 on December 31, 2024 in New York; 01:00 on January 1, 2025 in Paris; 09:00 on January 1, 2025 in Tokyo.

The timestamp itself does not change. Only the display changes. Timezones are a display concern — they should be resolved as late as possible, ideally in the presentation layer.

The best architecture: store UTC timestamps in your database, pass timestamps between services, and apply timezone only when generating output for a specific user.

UTC offsets vs. IANA timezone names

There are two ways to express a timezone:

  • UTC offset — a fixed offset from UTC: +01:00, -05:00. Simple, but static. Does not account for Daylight Saving Time changes. Use only for historical records or fixed-offset requirements.
  • IANA timezone name — a named zone from the IANA tz database: Europe/Paris, America/New_York, Asia/Tokyo. Encodes the full history of DST transitions for that region. Always prefer IANA names for user-facing timezone selection.

For example, America/New_York is UTC−5 in winter and UTC−4 in summer. Using the fixed offset -05:00 for a summer date would be wrong by one hour.

DST and timestamps

Daylight Saving Time transitions create two edge cases that require careful handling:

  • Spring forward (gap) — Clocks jump forward one hour. Local times like 2025-03-09 02:30:00 in America/New_York do not exist. If you try to build a timestamp from that string in that timezone, runtimes handle the gap differently (some round forward, some backward).
  • Fall back (overlap) — Clocks repeat an hour. Local times like 2024-11-03 01:30:00 in America/New_York occur twice. Without DST flag disambiguation, the earlier (EDT) or later (EST) occurrence is ambiguous.

Unix timestamps have no DST ambiguity. A timestamp always maps to exactly one UTC instant. The ambiguity only exists in the local-time representation. This is another reason to store timestamps as integers and resolve local time at display.

Common timezone bugs in code

  • Server timezone leaking into output. new Date().toLocaleString() in Node.js or date('Y-m-d') in PHP use the server's system timezone — which may differ from the user's.
  • Parsing a local string as UTC. new Date('2025-01-01 00:00:00') in JavaScript is parsed as local time. Append a Z or a +00:00 suffix to force UTC.
  • Using a UTC offset instead of an IANA name for recurring events. A meeting scheduled at 09:00 Europe/Paris stays at 9 AM regardless of DST. A meeting at 09:00 +01:00 shifts by one hour in summer because the offset is wrong for CEST.
  • Storing formatted dates in the database. If you store "2025-01-01 00:00:00" without a timezone, you lose the ability to correctly convert to another timezone later.

Best practices

  • Store all timestamps as UTC integers or TIMESTAMPTZ in PostgreSQL.
  • Collect the user's IANA timezone name at registration; store it alongside their data.
  • Apply the timezone only at the final rendering step — never in business logic.
  • Always pass an explicit timeZone to Intl.DateTimeFormat, toLocaleString(), and equivalents.
  • Use ISO 8601 with explicit offset (2025-01-01T01:00:00+01:00) when exchanging dates as strings between services.
  • Run your server in UTC (TZ=UTC). This eliminates server-local-time bugs entirely.

The Flowfiles converter lets you verify a timestamp in any IANA timezone instantly — useful when debugging a timezone mismatch between environments.