What is a Unix timestamp?
A Unix timestamp (also referred to as Epoch time or POSIX time) is the total number of seconds that have elapsed since 00:00:00 UTC on Thursday, 1 January 1970, not counting leap seconds.
For example, when a server records 1700000000, it represents exactly 2023-11-14T22:13:20Z in UTC.
Unix Timestamp = Total elapsed seconds since January 1, 1970 00:00:00 UTC
Despite its origins in the early days of Unix operating systems in the 1970s, the Unix timestamp remains the universal standard for logging, database indexing, and inter-system date exchange across virtually all modern operating systems and programming languages.
Why do computers use Unix timestamps instead of formatted dates?
Human calendar dates are notoriously difficult for computers to handle reliably:
- Timezone neutrality: Storing
"2026-10-06 14:30:00"is ambiguous unless the timezone offset is explicitly attached. A Unix timestamp always represents an absolute, universal instant in time identical for an observer in Tokyo, London, or New York. - Effortless time arithmetic: Calculating the difference between two events requires a simple integer subtraction (
timestampB - timestampA). Adding five minutes is as simple as adding300seconds. - Database performance and indexing: Comparing two 64-bit integers (
BIGINT) in a B-Tree index is dramatically faster and consumes less disk storage than parsing and comparing ISO date strings. - Daylight Saving Time (DST) immunity: Because Unix time counts linear seconds from UTC, it avoids the duplicate or skipped hours caused by biannual DST clock shifts.
The most common gotcha: Seconds vs. Milliseconds
The single most frequent bug when working with timestamps across different platforms is mixing up 10-digit seconds with 13-digit milliseconds:
| Unit | Digits | Example | Common Environments |
|---|---|---|---|
| Seconds | 10 | 1775468400 | Unix shell, Linux kernel, Python time.time(), PHP, Go, C/C++ |
| Milliseconds | 13 | 1775468400000 | JavaScript (Date.now()), Java (System.currentTimeMillis()) |
| Microseconds | 16 | 1775468400000000 | High-frequency trading, Python datetime timestamps, distributed tracing |
| Nanoseconds | 19 | 1775468400000000000 | Go time.Now().UnixNano(), Linux high-resolution timers |
Quick rule of thumb: If your timestamp has 10 digits, it is in seconds. If it has 13 digits, it is in milliseconds. If you feed a 10-digit timestamp into JavaScript's
new Date(timestamp), JavaScript will treat it as milliseconds in January 1970!
How to convert Unix timestamps in popular languages
JavaScript / TypeScript
In browser and Node.js environments:
// 1. Get current Unix timestamp (in seconds)
const currentSeconds = Math.floor(Date.now() / 1000);
// 2. Convert Unix timestamp (seconds) to human-readable Date
const timestamp = 1775468400;
const date = new Date(timestamp * 1000); // Multiply by 1000 for ms
console.log(date.toISOString()); // e.g. "2026-04-06T09:40:00.000Z"
console.log(date.toLocaleString()); // Local formatted string
// 3. Convert an existing Date object to Unix timestamp (seconds)
const epochSeconds = Math.floor(new Date("2026-10-06T12:00:00Z").getTime() / 1000);
Python
Python provides standard support through the time and datetime modules:
import time
from datetime import datetime, timezone
# 1. Get current Unix timestamp
current_timestamp = int(time.time())
# 2. Convert timestamp to timezone-aware UTC datetime
timestamp = 1775468400
utc_date = datetime.fromtimestamp(timestamp, tz=timezone.utc)
print(utc_date.strftime("%Y-%m-%d %H:%M:%S UTC"))
# 3. Convert datetime back to timestamp
ts = int(utc_date.timestamp())
Go (Golang)
In Go's standard time package:
package main
import (
"fmt"
"time"
)
func main() {
// 1. Current Unix timestamp
nowSeconds := time.Now().Unix()
nowMillis := time.Now().UnixMilli()
// 2. Convert timestamp to time.Time
t := time.Unix(1775468400, 0)
fmt.Println(t.UTC().Format(time.RFC3339))
}
SQL Databases
How to handle timestamps in common relational databases:
-- PostgreSQL
SELECT EXTRACT(EPOCH FROM NOW())::BIGINT; -- Get current timestamp
SELECT TO_TIMESTAMP(1775468400); -- Convert timestamp to timestamp with time zone
-- MySQL
SELECT UNIX_TIMESTAMP(); -- Get current timestamp
SELECT FROM_UNIXTIME(1775468400); -- Convert to DATETIME
-- SQLite
SELECT strftime('%s', 'now'); -- Current timestamp in seconds
SELECT datetime(1775468400, 'unixepoch'); -- Convert to readable text
The Year 2038 Problem (Y2038 / Epochalypse)
The Year 2038 problem is the computational equivalent of the Millennium Bug (Y2K).
Why does it happen?
Originally, Unix timestamps were stored as signed 32-bit integers (int32). A signed 32-bit integer has a maximum value of:
2^31 - 1 = 2,147,483,647
On Tuesday, 19 January 2038 at 03:14:07 UTC, a 32-bit timestamp will hit 2,147,483,647. One second later, the integer overflows into the negative numbers: -2,147,483,648, which corresponds to Friday, 13 December 1901.
Systems that still use 32-bit integers will either crash, calculate negative durations, or misinterpret scheduled database queries.
How is it fixed?
Modern operating systems, file systems, databases, and compilers have transitioned to signed 64-bit integers (int64 / BIGINT).
With a 64-bit integer, the maximum representable timestamp is:
2^63 - 1 ≈ 9.22 × 10^18 seconds
That is approximately 292 billion years into the future — well past the projected lifetime of the universe.
What about Leap Seconds?
Unix time is strictly linear and does not count leap seconds.
Every day in Unix time consists of exactly 86,400 seconds (60 × 60 × 24). When the International Earth Rotation and Reference Systems Service (IERS) inserts a leap second to keep clock time synchronized with the Earth's slowing rotation:
- In strict POSIX compliance, the timestamp repeat-counts or stalls during the leap second (
23:59:60is treated as23:59:59or00:00:00). - Major tech companies (such as Google, AWS, and Meta) use leap smearing, subtly stretching or slowing down seconds across a 24-hour window around the leap second so servers never witness abrupt clock jumps.
Summary and Best Practices
- Always store UTC: Store timestamps as UTC integers or UTC ISO strings in your persistence layer. Only format them into local timezones at the user interface boundary.
- Verify unit precision: Double-check whether an external API sends 10-digit seconds, 13-digit milliseconds, or fractional floats.
- Use 64-bit integers: Ensure your database columns are typed as
BIGINTrather than 32-bitINTto avoid the 2038 boundary. - Use browser-based tools for verification: Whenever you are troubleshooting API payloads, debugging JWT expiration claims (
exp), or inspecting database logs, verify values using our interactive Unix Timestamp Converter without sending sensitive tokens over the wire.