ToolSite

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.

By ToolSite5 min readguides

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. Enter 2147483647 (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.

Related Reading