What is Epoch Time? Unix Timestamps Explained for Developers
Every database, API, log file and programming language represents time as a number. That number — the Unix timestamp or epoch time — counts the seconds since a single fixed moment in history. Here's exactly what it is, why it works this way, and how to use it in every language.
The Definition
Epoch time (also called Unix time, Unix timestamp, or POSIX time) is the number of seconds that have elapsed since January 1, 1970 at 00:00:00 Coordinated Universal Time (UTC). This reference point is called the Unix epoch.
Think of it as an odometer for time — a continuously incrementing counter that every computer on the planet shares. Right now, that counter is somewhere around 1,715,000,000. Every second, it ticks up by one.
The current Unix timestamp is displayed live on the UnixLi homepage. You can paste any timestamp to convert it instantly — no signup, no ads, runs in your browser.
A Timeline of Epoch Time
Why January 1, 1970?
The choice of 1970 is often misunderstood. It has nothing to do with a special event in history. The early Unix developers needed a recent starting date that would keep timestamps small enough to fit in the available integer types of 1970s hardware. January 1st of a year near the development period was a natural choice.
The exact date was also influenced by practical trade-offs: going too far back would waste bits representing decades of negative or near-zero timestamps; going too far forward would delay the overflow problem unnecessarily. 1970 was a pragmatic compromise — and it stuck.
Interestingly, the very first version of Unix used a different epoch. Early Unix systems counted in 1/60th of a second intervals from January 1, 1971. The current Unix epoch was standardized later as part of POSIX.
How Epoch Time Works
The counter is straightforward: one second = one increment. But a few technical details matter:
- UTC, always. Epoch time is always in UTC, never in local time. Timezone conversions happen only when displaying to humans.
- Leap seconds are ignored. POSIX Unix time pretends leap seconds don't exist. A Unix day is always exactly 86,400 seconds, even though some real days have 86,401. This means Unix timestamps aren't perfectly continuous at leap second boundaries — a known limitation for high-precision timing systems.
- Negative values are valid. Timestamps before 1970 are represented as negative integers. The Moon landing happened at Unix timestamp
-14,182,940.
Seconds, Milliseconds, Microseconds, Nanoseconds
Different systems use different levels of precision. All of them count from the same epoch — just in smaller units.
The easiest way to identify precision: count the digits. 10 = seconds, 13 = milliseconds, 16 = microseconds, 19 = nanoseconds. See the full guide: Unix Seconds vs Milliseconds.
Famous Epoch Timestamps
Epoch time puts history on a number line. Some memorable moments, expressed as Unix timestamps:
Convert any timestamp — including the famous ones above
Paste 946684800 (Y2K), 1231006505 (Bitcoin genesis), or any other timestamp into UnixLi for the full conversion: UTC, local time, ISO 8601, SQL, relative time and code snippets.
Why Developers Use Epoch Time
Given that humans can't read 1715429912 directly, why is it the universal standard?
- Timezone-free. A Unix timestamp has exactly one meaning everywhere on Earth. There's no "which timezone?" ambiguity.
1715429912is the same moment in Tokyo, Paris, and New York. - Simple arithmetic. "What was 7 days ago?" is
now - 604800. "Is this token expired?" isnow > exp. Date math that would require libraries becomes a subtraction. - Sortable by default. Timestamps sort correctly as integers, with no parsing, locale, or format concerns.
- Compact storage. A 64-bit integer (8 bytes) stores a timestamp with nanosecond precision. A readable date string like "2026-05-11T14:38:32Z" takes 20 bytes.
- Universal support. Every database, every language, every operating system has native Unix timestamp support.
How to Get the Current Epoch Time
// Unix seconds
const nowSec = Math.floor(Date.now() / 1000); // 1715429912
// Unix milliseconds
const nowMs = Date.now(); // 1715429912000
import time
now_sec = int(time.time()) # 1715429912
now_ms = time.time_ns() // 1_000_000 # 1715429912000
// PHP
$now = time(); // 1715429912
// Go
now := time.Now().Unix() // seconds
nowMs := time.Now().UnixMilli() // milliseconds
// Rust
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
-- PostgreSQL
SELECT EXTRACT(EPOCH FROM NOW())::BIGINT; -- 1715429912
-- MySQL / MariaDB
SELECT UNIX_TIMESTAMP(); -- 1715429912
The Year 2038 Problem
Many legacy systems store Unix timestamps as a signed 32-bit integer. The maximum value of a signed 32-bit integer is 2,147,483,647 — which corresponds to January 19, 2038 at 03:14:07 UTC. One second later, the counter overflows to -2,147,483,648 — wrapping back to December 13, 1901.
Am I affected? Modern 64-bit systems (Linux, macOS, Windows since the 2000s) are not affected — they use 64-bit timestamps. But embedded systems, legacy databases, some IoT devices, and old file systems may still use 32-bit timestamps. If you're writing code that stores timestamps in a database column typed as INT instead of BIGINT, you're creating a 2038 time bomb.
-- ❌ WRONG — will overflow in 2038
created_at INT NOT NULL,
-- ✅ CORRECT — safe until year 292 billion
created_at BIGINT NOT NULL,
-- ✅ ALSO CORRECT — database-native type handles this automatically
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
Epoch Time vs ISO 8601 — When to Use Which
| Criterion | Epoch time (Unix seconds) | ISO 8601 (2026-05-11T14:38:32Z) |
|---|---|---|
| Storage size | 8 bytes (BIGINT) | 20–25 bytes (string) |
| Comparison / sorting | Integer comparison — instant | String comparison — locale-sensitive |
| Arithmetic | Simple subtraction | Requires parsing and libraries |
| Human readability | Not readable | Immediately readable |
| Timezone information | Always UTC, implicit | Explicit (can include offset) |
| Best for | Storage, APIs, comparisons, JWT | Logs, user display, data exchange |
| Interoperability | Universal | Universal (ISO standard) |
Best practice: store as Unix seconds, display as ISO 8601. Use Unix timestamps in your database and API layer for efficient arithmetic and storage. Convert to ISO 8601 at the display layer, where human readability matters.
Quick Reference
| Concept | Value |
|---|---|
| The Unix Epoch | 0 = January 1, 1970 00:00:00 UTC |
| 1 minute in seconds | 60 |
| 1 hour in seconds | 3,600 |
| 1 day in seconds | 86,400 |
| 1 week in seconds | 604,800 |
| 1 year ≈ in seconds | 31,536,000 (365 days) |
| 32-bit max (2038 limit) | 2,147,483,647 |
| 64-bit max | 9,223,372,036,854,775,807 |
| 10-digit → seconds | 2001–2286 range |
| 13-digit → milliseconds | 2001–2286 range |
Summary
Epoch time is the number of seconds since January 1, 1970 UTC. It's not a format or a standard owned by any organization — it's a convention that emerged from early Unix development and became the universal language of time in software because it's simple, timezone-free, and trivially computable.
The practical rules: always store in 64-bit integers (not 32-bit), always compare in the same unit (don't mix seconds and milliseconds), and always convert to UTC before doing any arithmetic.
Next steps: convert Unix timestamps in JavaScript, understand the seconds vs milliseconds distinction, or decode JWT expiration claims.