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.
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: 1700000000 → 2023-11-14T22:13:20Z (UTC)
- The value is usually an integer and contains no time-zone information (it is always relative to UTC).
- One day is counted as
86400seconds (60×60×24). - Future moments are large positive values; moments before the epoch (before 1970) are negative.
- "Unix timestamp", "epoch seconds", and "POSIX time" are used to mean essentially the same thing.
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.
| Unit | Example (same moment) | Typical digits |
|---|---|---|
| Seconds | 1700000000 | 10 digits |
| Milliseconds | 1700000000000 | 13 digits |
- Milliseconds to seconds:
Math.floor(Date.now() / 1000) - Seconds (e.g.
1700000000) to a JavaScriptDate:new Date(1700000000 * 1000)
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 zone | How 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.
- UTC is shown with a trailing
Z(Zulu):2023-11-14T22:13:20Z. - An offset is written like
+09:00:2023-11-15T07:13:20+09:00(the same instant as above). - The separator between date and time is an uppercase
T. Milliseconds are appended as a fraction such as.123.
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.
- By the POSIX convention, the calculation treats "one day = exactly 86400 seconds." It does not count the actual leap seconds in UTC.
- As a result, Unix time does not exactly equal the true number of elapsed seconds (the accumulation of SI seconds). It drifts from the theoretical value by the number of leap seconds.
- Many systems reconcile this by reusing the same second value twice at the moment of a leap second, or by slowing the clock slightly (leap smear).
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).
| Item | 32-bit signed | 64-bit signed |
|---|---|---|
| Largest representable Unix time | 2147483647 | about 9.2×1018 |
| When the ceiling is reached | 2038-01-19 03:14:07 UTC | about 290 billion years from now |
| Behavior when exceeded | Wraps to a negative value (1901) | Effectively a non-issue |
| Remedy | Widening to 64 bits required | Already 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.
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.