Unix Timestamps Explained: Seconds, Milliseconds, and the Y2K38 Problem
Unix timestamps are the lingua franca of time in software. Every language can generate and parse them. But seconds vs milliseconds trips up almost every developer at least once โ and the Y2K38 problem is coming.
What a Unix timestamp is
A Unix timestamp is the number of seconds (or milliseconds, depending on the system) that have elapsed since January 1, 1970, 00:00:00 UTC โ the "Unix epoch." It's timezone-independent, which is why it's the standard for storing and transmitting time in systems.
// Current timestamp in different languages JavaScript: Date.now() // milliseconds โ 1720000000000 Python: time.time() // seconds (float) โ 1720000000.12 Go: time.Now().Unix() // seconds โ 1720000000 Rust: SystemTime::now() // Duration since epoch SQL: EXTRACT(EPOCH FROM NOW()) // PostgreSQL, seconds
The seconds vs milliseconds problem
This is the most common source of timestamp bugs. JavaScript Date.now() returns milliseconds. Almost every other language and API returns seconds. Pass a millisecond timestamp to code expecting seconds and you get a date in the year 56,000.
// Detect: if > 9,999,999,999 it's probably milliseconds const isMs = (ts: number) => ts > 9_999_999_999 // Convert JS Date.now() to seconds: const seconds = Math.floor(Date.now() / 1000) // Convert seconds to JS Date: const date = new Date(seconds * 1000)
The Y2K38 problem
Many older systems store Unix timestamps as a signed 32-bit integer. The maximum value is 2,147,483,647 โ which represents January 19, 2038 at 03:14:07 UTC. After that moment, a 32-bit signed integer wraps to a large negative number: January 13, 1901.
Systems at risk: embedded systems, 32-bit Linux systems, older databases, PHP time() on 32-bit platforms, MySQL TIMESTAMP column type (max 2038-01-19).
Fix: Use 64-bit integers for timestamps. In MySQL, use DATETIME instead of TIMESTAMP. In PostgreSQL, TIMESTAMP is already 64-bit and safe until year 294276.
Notable timestamps
0
Unix Epoch
Jan 1, 1970 00:00:00 UTC
946684800
Y2K
Jan 1, 2000 00:00:00 UTC
1000000000
10^9 seconds
Sep 9, 2001 โ dev milestone
2147483647
Y2K38 boundary
Jan 19, 2038 โ 32-bit max
Conversion across languages
// JavaScript โ convert timestamp to human-readable
const ts = 1720000000
new Date(ts * 1000).toISOString() // "2024-07-03T12:26:40.000Z"
new Date(ts * 1000).toLocaleString("en-US", { timeZone: "America/New_York" })
// Python
import datetime
datetime.datetime.fromtimestamp(1720000000, tz=datetime.timezone.utc)
// Go
time.Unix(1720000000, 0).UTC().Format(time.RFC3339)
// SQL (PostgreSQL)
SELECT to_timestamp(1720000000) AT TIME ZONE 'UTC';Convert any Unix timestamp instantly โ including timezone support and code snippets for all major languages โ with the Unix Timestamp Converter.
Try the related tool
Unix Timestamp Converter โ free, runs 100% in your browser.
Open Unix Timestamp Converter โEnjoyed this? Get notified when Pro launches.
