What Is a Unix Timestamp? Epoch Time Explained
Understand Unix timestamps: what epoch time is, why January 1 1970, how 32-bit overflow causes the Year 2038 problem, and how to convert timestamps instantly.
A Single Number for Time
A Unix timestamp is the number of seconds that have elapsed since 00:00:00 UTC on January 1, 1970, not counting leap seconds. That moment is called the Unix epoch.
1700000000 = November 14, 2023 at 10:13:20 PM UTC
0 = January 1, 1970 at 00:00:00 UTC
Every moment in computing history is just an integer relative to that one reference point. No timezones. No date strings. No formatting ambiguity. This simplicity is why timestamps are the backbone of logs, databases, APIs, and every scheduling system.
Why January 1, 1970?
The epoch was chosen arbitrarily by early Unix engineers at Bell Labs. It was a convenient round number in the recent past when they were designing the system in the early 1970s. No deeper reason. It stuck because Unix stuck, and every system that followed adopted the same convention.
Some systems use different epochs. GPS time starts at January 6, 1980. Windows NT uses January 1, 1601 (the start of the Gregorian calendar cycle). NTP uses January 1, 1900. But Unix time won. It is the default in every language, OS, and protocol you work with daily.
How Timestamps Work Under the Hood
A Unix timestamp is a signed integer. The original specification used a signed 32-bit integer. At midnight UTC on January 1, 1970, the counter is 0. Each second, the counter increments by 1. Negative values represent dates before the epoch.
Current timestamp (now): approximately 1.77 billion
Timestamp one hour ago: current minus 3600
Timestamp tomorrow: current plus 86400
The arithmetic is trivially simple. To find the difference between two instants,
subtract one timestamp from the other. To add 30 days, add 30 * 86400. No
calendar logic, no month-length tables, no leap-year calculations.
Integer Representation
A signed 32-bit integer can represent dates from:
-2,147,483,648 = December 13, 1901 at 8:45:52 PM UTC
2,147,483,647 = January 19, 2038 at 3:14:07 AM UTC
After January 19, 2038, a 32-bit signed integer overflows and wraps around to December 13, 1901. This is the Year 2038 problem . the 32-bit cousin of Y2K.
The Year 2038 Problem
Systems that still use 32-bit time_t will fail on January 19, 2038. The
counter overflows and becomes negative, which most software interprets as a
date in 1901. Date comparisons break. Schedules fire 136 years late. Logs show
impossible timestamps.
The fix is straightforward: use a 64-bit integer. A 64-bit Unix timestamp
covers approximately 292 billion years in both directions . roughly 20 times
the age of the universe. Modern operating systems (64-bit Linux, macOS, any
recent BSD) use 64-bit time_t by default.
The risk surface is shrinking but not gone. Embedded systems, legacy databases, 32-bit binaries, and old firmware are the concern. A router from 2010 running a 32-bit Linux kernel will misinterpret dates after 2038. Some financial systems still run on 32-bit mainframe emulators.
Real-World Impact of Timestamp Overflow
The Year 2038 problem has already caused issues with future-date calculations. Mortgage calculators, certificate expiration checks, and long-term scheduling systems that project dates past 2038 hit the overflow on 32-bit systems today.
A certificate with a 20-year validity issued in 2025 exceeds the 32-bit range.
A database column defined as INT for timestamps can't store dates after 2038.
Migrating those columns to BIGINT (64-bit) is a non-trivial schema change on
large tables.
Milliseconds and Microseconds
Many systems use millisecond or microsecond precision by storing a larger number:
1700000000000 = milliseconds since epoch (13 digits)
1700000000000000 = microseconds since epoch (16 digits)
JavaScript's Date.now() returns milliseconds. Python's time.time() returns
seconds as a float (microsecond precision on most platforms). When you see a
13-digit timestamp in a JSON API, it's milliseconds. A 10-digit timestamp is
seconds. A 16-digit timestamp is microseconds.
This matters when you pass timestamps between systems. A Python script that expects seconds but receives milliseconds interprets the value as a date 54,000 years in the future. Always check the digit count.
Leap Seconds
Unix timestamps ignore leap seconds. When a leap second is inserted, the Unix clock either repeats a second or smears the adjustment across a longer period (Google's leap smear approach). This means Unix time is not a true count of SI seconds since the epoch . it drifts by the accumulated leap seconds (27 as of 2024).
For most applications, this doesn't matter. For astronomical calculations, satellite tracking, or anything needing sub-second accuracy over decades, you need a time system that accounts for leap seconds (like TAI or GPS time).
Converting in Code
// JavaScript: timestamp to date
new Date(1700000000 * 1000).toISOString()
// "2023-11-14T22:13:20.000Z"
// JavaScript: date to timestamp
Math.floor(Date.now() / 1000)
# Python: timestamp to date
import datetime
datetime.datetime.fromtimestamp(1700000000, tz=datetime.timezone.utc)
# datetime.datetime(2023, 11, 14, 22, 13, 20, tzinfo=datetime.timezone.utc)
# Python: date to timestamp
import time
int(time.time())
# Linux/macOS: current timestamp
date +%s
# 1700000000
# Convert timestamp to date
date -d @1700000000
# Tue Nov 14 22:13:20 UTC 2023
Using the Converter
The Unix Timestamp Converter converts in both directions: enter a timestamp to see the human-readable date in your local timezone, or pick a date and time to get the Unix timestamp. It handles millisecond and microsecond inputs automatically.
Try it yourself: open the Unix Timestamp Converter. Enter
0(the epoch) and see it resolve to January 1, 1970 at midnight UTC. Enter2147483647(the maximum 32-bit timestamp) and see January 19, 2038. Then add one second (2147483648) to see the overflow into 1901 on a 32-bit system. Enter a 13-digit millisecond timestamp from a JavaScript API response.