Songtov Utility
Back to Blog

Unix Timestamps Explained: Seconds, Milliseconds, UTC, and Timezones

A practical guide to Unix epoch time for developers, including seconds vs milliseconds, timezone display, JWT dates, database fields, and log debugging.

CS
Chiho Song

Software Developer · Songtov Utility

What a Unix Timestamp Represents

A Unix timestamp counts time from 00:00:00 UTC on January 1, 1970. The idea is intentionally boring: represent a moment as a single number. Computers can compare, sort, store, and transmit that number without worrying about month names, daylight saving time labels, or local date formats.

The number itself is timezone-neutral. Timezone only appears when you display that number to a human.

Seconds vs Milliseconds

Many systems store Unix time in seconds. JavaScript, however, uses milliseconds for Date.now() and the Date constructor. That difference causes a classic bug:

new Date(1710000000)

The code above treats the value as milliseconds, so it displays a date in January 1970. To use epoch seconds in JavaScript, multiply by 1000:

new Date(1710000000 * 1000)

As a quick rule, current epoch seconds are about 10 digits long. Current epoch milliseconds are about 13 digits long.

UTC Is the Reference Point

UTC is the shared reference. If a timestamp says an event happened at a particular instant, that instant is the same everywhere. Your local timezone only changes the wall-clock display.

For example, a UTC evening timestamp may appear as the next morning in Seoul. The event did not move; your local calendar view changed.

Where Developers See Timestamps

  • JWT claims such as exp, iat, and nbf.
  • Database columns that store creation or expiration times.
  • Server logs from distributed systems.
  • Cache headers and signed URL expiration values.
  • Webhook payloads from payment, messaging, and automation services.

Common Real-World Timestamp Bugs

Timestamp bugs are frustrating because the value often looks valid. The code runs, the database stores a number, and the UI shows a date. The problem is that the date is wrong.

JWT expiration looks like 1970

JWT claims such as exp and iat are commonly represented as epoch seconds. JavaScript Date, however, expects milliseconds. If you pass a JWT exp value directly into new Date(), the displayed date can land near January 1970.

The fix is not to change the token. The fix is to multiply by 1000 when converting seconds to a JavaScript date.

Webhook events arrive "in the future"

Webhook payloads often include event creation times. If your application compares provider timestamps with server-local time, timezone display can make a valid event look like it arrived tomorrow or yesterday.

When debugging this, compare ISO UTC strings first. Only convert to local display time after you know the instant is correct.

Cache expiration uses a different unit

One system may store TTL in seconds, another in milliseconds. Setting 3600 can mean one hour in a cache API, but only 3.6 seconds in a JavaScript timer if the code expected milliseconds.

That mismatch causes bugs that feel random: sessions expire immediately, signed URLs last too long, or background jobs retry at the wrong interval.

Database timestamps mix dates and instants

An instant like created_at should represent one exact moment. A calendar date like birth_date or billing_date is different. If you store both as timestamps and convert everything through local time, users near timezone boundaries can see off-by-one-day errors.

The debugging question is: are you storing an instant, or are you storing a date-only concept?

Debugging Time Bugs

Start by identifying the unit. If a value looks 1000 times too early or too late, seconds and milliseconds are probably mixed. Next, check whether the displayed date is local time or UTC. Finally, confirm whether the system stores an instant in time or a calendar date without time.

Those are different concepts. A birthday is a date. A login event is an instant. Treating them the same is how timezone bugs sneak into otherwise ordinary code.

Debugging Checklist

  • Count the digits: current epoch seconds are usually 10 digits; milliseconds are usually 13.
  • Convert the raw value to UTC first, then local time.
  • Check whether the source system documents seconds, milliseconds, or ISO strings.
  • For JWTs, remember that exp, iat, and nbf are typically epoch seconds.
  • For JavaScript timers, remember that setTimeout and Date use milliseconds.
  • Do not store date-only values as local midnight timestamps unless you control the timezone rules.
  • Log both the raw timestamp and the rendered ISO string during debugging.

Practical Examples

A value such as 1710000000 is likely seconds. It represents a plausible modern date after multiplying by 1000 for JavaScript display.

A value such as 1710000000000 is likely milliseconds. Multiplying it again creates a date far in the future.

An ISO value such as 2026-07-08T07:00:00Z already includes UTC information. Do not parse it, convert it to local time, then compare the local string with a UTC string.

Use the Tool

Use the Unix Timestamp Converter to convert epoch values into local, UTC, ISO, and date-only formats while debugging logs and payloads.

Try it yourself

Use our free Unix Timestamp Converter

Open Unix Timestamp Converter