Unix Time Explained

Unix time is the number of seconds that have passed since 00:00:00 UTC on 1 January 1970, not counting leap seconds. It has no time zone, so the same number means the same moment everywhere. Most systems count in seconds (10 digits today), but JavaScript and Java count in milliseconds (13 digits).

Seconds vs milliseconds

The quickest test is to count digits. A timestamp from this decade has 10 digits in seconds and 13 in milliseconds. Mixing them up is the most common bug: treat seconds as milliseconds and you land in January 1970; treat milliseconds as seconds and you land tens of thousands of years in the future.

Date.now()                  // 1762245000000  (milliseconds)
Math.floor(Date.now()/1000) // 1762245000     (seconds)
new Date(1762245000 * 1000) // seconds → Date: multiply by 1000

Time zones

A timestamp is an instant, not a wall-clock time. Converting it to "09:30" requires a time zone, and that is the only point where time zones should enter. Store and compare instants in UTC or as timestamps; convert to the user's zone only when you display them.

Leap seconds

Unix time pretends every day has exactly 86,400 seconds. When a leap second is added to UTC, Unix time repeats or smears a second, so the difference between two timestamps is not always the exact number of physical seconds between them. For almost all applications this does not matter, and leap seconds are due to be phased out by 2035.

The year 2038 problem

A signed 32-bit integer can hold up to 2,147,483,647. As a Unix timestamp, that is 03:14:07 UTC on 19 January 2038. One second later, a 32-bit counter wraps around to a negative number, which reads as December 1901. 64-bit systems, modern languages and current databases use 64-bit time and are not affected, but embedded devices, old file formats and database columns declared as 32-bit INT still are.

Converting in common languages

# Python
import time, datetime
int(time.time())
datetime.datetime.fromtimestamp(1762245000, tz=datetime.timezone.utc)

// Go
time.Now().Unix()
time.Unix(1762245000, 0).UTC()

-- PostgreSQL
SELECT extract(epoch FROM now())::bigint;
SELECT to_timestamp(1762245000);

# Shell (GNU date)
date +%s
date -u -d @1762245000

Or paste any timestamp into the Unix timestamp converter.

Frequently asked questions

Why does Unix time start in 1970?

The early Unix developers needed a recent, round starting point when they designed the system around 1970–71. 1 January 1970 00:00:00 UTC was chosen and has stayed the standard since.

Can a Unix timestamp be negative?

Yes. Negative values count backwards from 1970, so -86400 is 31 December 1969 at 00:00 UTC. Most modern languages handle them, but some older systems and databases do not.

Should I store dates as timestamps or as ISO strings?

In a database, use the native timestamp type (in PostgreSQL, timestamptz), which stores an instant and converts for display. In JSON APIs, ISO 8601 strings with a UTC offset, such as 2026-11-04T09:30:00Z, are readable and unambiguous. Raw numbers are fine too, as long as everyone agrees whether they are seconds or milliseconds.

Tools for this guide