What Is Unix Time? Epoch Seconds, Time Zones, and Year 2038

Unix time (epoch seconds, a Unix timestamp) represents a moment as the number of seconds elapsed since 1970-01-01 00:00:00 in Coordinated Universal Time (UTC). Because it expresses time as a single, time-zone-independent integer, it is widely used to exchange time between computers in logs, databases, and APIs. This article lays out, accurately, the definition of Unix time, seconds vs. milliseconds, time zones and UTC, ISO 8601, leap seconds, and the Year 2038 problem.

The bottom line first: Unix time is the number of seconds elapsed from 1970-01-01 00:00:00 UTC as zero. The timestamp itself contains no offset; you convert to a time zone only when displaying it. Systems that store it in 32 bits hit their ceiling in 2038, so widening to 64 bits is required.

1. What Unix time is — seconds since 1970

Unix time uses 1970-01-01 00:00:00 UTC as its origin (called the epoch) and represents a moment as the number of seconds elapsed from it. The epoch itself is 0, and one second later is 1.

Example: 17000000002023-11-14T22:13:20Z (UTC)

Because a moment collapses into a single number, sorting and computing differences (elapsed time = subtraction) become very simple.

2. Seconds vs. milliseconds — watch the factor of 1000 in JavaScript

Unix time is originally measured in seconds, but some languages and libraries use milliseconds. The classic example is JavaScript, whose Date.now() and getTime() return milliseconds.

UnitExample (same moment)Typical digits
Seconds170000000010 digits
Milliseconds170000000000013 digits
Watch out for the mix-up. Confusing seconds and milliseconds shifts the time by about a factor of 1000 (for instance, interpreting a seconds value as milliseconds lands you in the 1970s). Checking the number of digits (roughly 10 for seconds, 13 for milliseconds) is a safe sanity check.

3. Time zones and UTC — the value is UTC, conversion is for display

The most commonly misunderstood point about Unix time is its relationship with time zones. The timestamp itself is always relative to UTC and carries no offset. "Is this JST or UTC?" only matters when you convert the number into a human-readable form for display.

For example, the same value 1700000000 looks different depending on the display time zone.

Time zoneHow the same value 1700000000 displays
UTC (±0)2023-11-14 22:13:20
Japan time (JST, UTC+9)2023-11-15 07:13:20

JST is nine hours ahead of UTC, so the display shifts by +9 hours, but the underlying timestamp value does not change. The standard practice is to exchange UTC timestamps between servers and convert to the user's local time zone only just before showing it.

4. ISO 8601 notation — the standard human-readable format

Unix time is convenient for machines but unreadable to people as-is. So the international standard ISO 8601 for representing dates and times as strings is commonly used alongside it. The basic format is YYYY-MM-DDThh:mm:ss, with the time zone indicated at the end.

Key point: for the same instant, 2023-11-14T22:13:20Z and 2023-11-15T07:13:20+09:00 point to exactly the same Unix time (1700000000). Because ISO 8601 can state the offset explicitly, it removes ambiguity in API exchanges. Avoid bare date-time strings with no time zone, since they are interpreted inconsistently.

5. Leap seconds — POSIX time ignores them

Because the Earth's rotation is not perfectly uniform, a leap second is occasionally inserted into UTC, making a minute 61 seconds long. However, Unix time (POSIX time) is defined to ignore leap seconds.

What this means in practice: ordinary applications rarely need to worry about leap seconds. But for uses where nanosecond-precise measurement or behavior across the leap-second instant matters (finance, scientific measurement, etc.), you should be aware that systems handle them differently.

6. The Year 2038 problem — 32-bit overflow

Many older systems stored Unix time in a type called time_t as a 32-bit signed integer. The largest value a signed 32-bit integer can hold is 2147483647 (about 2.1 billion). Unix time reaches that value at 2038-01-19 03:14:07 UTC.

One second past that ceiling, the integer overflows and wraps to its most negative value, jumping the clock back to around 1901-12-13. This is the Year 2038 problem (Y2K38).

Item32-bit signed64-bit signed
Largest representable Unix time2147483647about 9.2×1018
When the ceiling is reached2038-01-19 03:14:07 UTCabout 290 billion years from now
Behavior when exceededWraps to a negative value (1901)Effectively a non-issue
RemedyWidening to 64 bits requiredAlready solved

The fix is simple: widen time_t to 64 bits. A 64-bit signed integer can represent hundreds of billions of years, so on any human timescale it effectively never overflows. Most modern 64-bit operating systems and language runtimes already use a 64-bit time type, so a new system usually has nothing to worry about. However, if old 32-bit environments, embedded devices, or legacy data formats remain, you need to consider migrating them.

Free Tool Try it for real with the Unix time converter Convert between Unix time (seconds and milliseconds) and dates, and check the display in both UTC and your local time zone. Everything runs in your browser.

Frequently Asked Questions (FAQ)

What is Unix time?

Unix time (also called epoch seconds or a Unix timestamp) represents a moment as the number of seconds elapsed since the epoch, which is 1970-01-01 00:00:00 in Coordinated Universal Time (UTC). Because it expresses time as a single, time-zone-independent integer, it is widely used to exchange time between computers in logs, databases, and APIs. For example, 1700000000 represents 2023-11-14T22:13:20Z (UTC).

Is Unix time in seconds or milliseconds?

Unix time is originally measured in seconds. However, JavaScript's Date.now() and getTime() return milliseconds, so you must divide by 1000 to convert to seconds. Conversely, when passing a seconds timestamp to a JavaScript Date you multiply by 1000 to get milliseconds. Confusing seconds and milliseconds shifts the time by about a factor of 1000, so check the number of digits (roughly 10 digits for seconds, 13 for milliseconds) to stay safe.

What is the Year 2038 problem?

The Year 2038 problem is that systems storing Unix time in a 32-bit signed integer will overflow just after 2038-01-19 03:14:07 UTC, wrapping around to a negative value (such as 1901). The largest value a 32-bit signed integer can hold is 2147483647, which corresponds exactly to that moment. The fix is to widen time_t to 64 bits; a 64-bit value can represent hundreds of billions of years, so the problem is effectively eliminated.

← Back to the Tech Blog list