Skip to content
PithLab

↑↓ to move · Enter to open · Esc to close

Unix timestamps and time zones, explained

· 3 min read

A Unix timestamp is the number of seconds since 00:00:00 UTC on 1 January 1970, ignoring leap seconds. That's it. 0 is the start of 1970, 1700000000 is 22:13:20 UTC on 14 November 2023, and right now the number is a little over 1.7 billion and climbing by one every second.

Timestamps are popular because they're unambiguous. A single number means the same instant everywhere on Earth, whatever the local clock says. The trouble starts when we convert them to and from human dates.

Seconds or milliseconds?

The most common timestamp bug is a factor of 1,000.

  • Unix tools, most databases and many APIs use seconds: 1700000000.
  • JavaScript's Date.now() and Java's System.currentTimeMillis() use milliseconds: 1700000000000.

Treat a milliseconds value as seconds and you get a date about 54,000 years in the future. Treat seconds as milliseconds and you land in January 1970. A quick rule: today's timestamps have 10 digits in seconds and 13 in milliseconds.

The Unix timestamp converter tells seconds from milliseconds by the size of the number and shows the date in UTC and your local time, so you can see at a glance which one you've got.

Time zones only matter at the edges

A timestamp has no time zone. Time zones come in when you display it or parse a date someone typed.

The same instant, 1700000000, is:

Place Local time
UTC 14 Nov 2023, 22:13:20
London (GMT) 14 Nov 2023, 22:13:20
New York (EST, UTC−5) 14 Nov 2023, 17:13:20
Tokyo (JST, UTC+9) 15 Nov 2023, 07:13:20

Note the date changes in Tokyo. If you store "14 November" without a time zone, you've lost information.

Store UTC, show local

The pattern that avoids most bugs:

  1. Store instants in UTC, as a timestamp or as an ISO 8601 string with an offset, like 2023-11-14T22:13:20Z.
  2. Convert to local time only for display, using the viewer's time zone.
  3. Store the time zone name (like Europe/London) alongside future events that happen at a local time, such as "every Monday at 09:00". An offset like +01:00 isn't enough, because it changes with daylight saving.

That third point catches people out. A meeting at 09:00 London time is at 08:00 UTC in summer and 09:00 UTC in winter. If you saved it as a fixed UTC time, it moves by an hour twice a year. The time zone converter shows how a time lines up across zones on a particular date, including daylight saving changes.

Counting days is harder than it looks

"How many days until the deadline?" sounds like subtracting two timestamps and dividing by 86,400. But on the day clocks change, a local day lasts 23 or 25 hours, so dividing can give you 6.96 days instead of 7. For calendar maths, work with dates rather than seconds, which is what the date difference calculator does.

The year 2038

Systems that store Unix time in a signed 32-bit integer can only count up to 2,147,483,647, which is 03:14:07 UTC on 19 January 2038. One second later, the value wraps to a large negative number, a date in December 1901. Modern operating systems and languages use 64-bit time, but old embedded devices, file formats and database columns declared as 32-bit integers still exist. If you're designing a schema today, use a 64-bit integer or a proper timestamp type.

Checklist

  • Know whether each API uses seconds or milliseconds, and name fields accordingly (createdAtMs).
  • Store instants in UTC; store a time zone name for future local-time events.
  • Convert for display as late as possible.
  • Use date arithmetic, not seconds, for "days between".
  • Avoid 32-bit timestamp columns.

Tools in this post

Keep reading

  • Cron expressions explained with 12 examples

    Five fields, a few symbols and a lot of confusion. Learn to read and write cron schedules with 12 real examples, plus the time zone and day-of-week traps to avoid.

  • JSON vs YAML: when to use which

    JSON and YAML describe the same data, but they fail in different ways. A practical guide to choosing between them, with the YAML gotchas that bite in production.

  • How to read a JWT without leaking it

    A JSON Web Token is just three Base64url chunks. Here's how to read the header and claims, what to check, and why you should never paste one into a random site.