ESC
Developer

Unix Timestamps Explained: What Is Epoch Time and How to Use It

Understand what Unix timestamps are, why they start at January 1 1970, how to convert them, and the timezone traps every developer falls into.

2026-06-29 7 min read Developer
Unix Timestamp / Epoch Time Guide

What Is a Unix Timestamp?

A Unix timestamp (also called epoch time or POSIX time) is simply the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC. That specific moment is called the Unix epoch.

Example: The timestamp 1735689600 represents January 1, 2025, 00:00:00 UTC. Right now the timestamp is somewhere around 1.75 billion — every second that number ticks up by 1.

Why January 1, 1970?

Unix was developed at Bell Labs in the late 1960s. When the engineers needed a reference point for time, they picked the start of 1970 because it was a round, recent date that fit neatly in the integer types of the era. There is nothing magical about 1970 — it was a practical choice that stuck.

Some systems use different epochs: GPS time starts January 6, 1980; Windows FILETIME starts January 1, 1601. Whenever you see an unexpectedly large or negative timestamp, a mismatched epoch is usually the culprit.

Seconds vs Milliseconds — The Most Common Bug

Modern JavaScript uses milliseconds since epoch (Date.now() returns ~1,750,000,000,000), while most Unix tools use seconds. Mixing the two is the single most common timestamp bug:

// JavaScript — milliseconds
Date.now()              // → 1750000000000 (13 digits)

// Bash / Python / PHP — seconds
date +%s                // → 1750000000 (10 digits)
time.time()             // Python
time()                  // PHP

Quick rule: if your timestamp has 13 digits it is milliseconds; 10 digits means seconds. Divide by 1000 to convert JavaScript time to Unix seconds.

Converting Timestamps in Code

JavaScript

// Current timestamp (ms)
const now = Date.now();

// Timestamp → Date object
const d = new Date(1735689600 * 1000);  // multiply seconds by 1000
console.log(d.toISOString());           // "2025-01-01T00:00:00.000Z"

// Date → timestamp (seconds)
const ts = Math.floor(new Date("2025-01-01").getTime() / 1000);

Python

import datetime, time

# Current timestamp
ts = int(time.time())

# Timestamp → datetime (UTC)
dt = datetime.datetime.utcfromtimestamp(1735689600)
print(dt)  # 2025-01-01 00:00:00

# datetime → timestamp
ts = int(datetime.datetime(2025, 1, 1, tzinfo=datetime.timezone.utc).timestamp())

PHP

// Current timestamp
$ts = time();

// Timestamp → readable string
echo date("Y-m-d H:i:s", 1735689600);   // 2025-01-01 00:00:00 (server timezone!)

// Use gmdate() for UTC output
echo gmdate("Y-m-d H:i:s", 1735689600); // always UTC

// String → timestamp
$ts = strtotime("2025-01-01 00:00:00 UTC");

The Timezone Trap

A Unix timestamp is always UTC — it has no timezone. The confusion happens during conversion: when you call date() in PHP or format a Date object in JavaScript without specifying a timezone, the output uses the server or system timezone. This is how "2025-01-01" becomes "2024-12-31" in production.

Rule: Store timestamps in UTC. Convert to the user's local timezone only at display time. Never store a "local" timestamp without the timezone offset.

The Year 2038 Problem

32-bit signed integers can hold values up to 2,147,483,647. On January 19, 2038 at 03:14:07 UTC, a 32-bit Unix timestamp overflows and wraps to a large negative number — interpreting it as December 13, 1901.

Modern 64-bit systems are not affected (they can represent dates hundreds of billions of years in the future). But embedded systems, old databases, and legacy C code using int32_t for time are still at risk. MySQL's TIMESTAMP type was affected until version 8.0.28 which extended it using 64-bit storage.

Useful Timestamp Values to Know

TimestampDate (UTC)Notes
01970-01-01 00:00:00Unix epoch
10000000002001-09-09 01:46:401 billion seconds
17000000002023-11-14 22:13:201.7 billion seconds
21474836472038-01-19 03:14:07Max 32-bit signed int
42949672952106-02-07 06:28:15Max 32-bit unsigned int

Frequently Asked Questions

Why is my timestamp negative?

A negative Unix timestamp represents a date before January 1, 1970. For example, -86400 is December 31, 1969 at 00:00:00 UTC. It's also what you get when a 32-bit system overflows in 2038.

What is the difference between epoch time and Unix time?

Nothing — they are the same thing. "Epoch time", "Unix time", "Unix timestamp", and "POSIX time" all refer to seconds elapsed since January 1, 1970 UTC. The word "epoch" just means the reference point in a time system.

How do I convert a timestamp with milliseconds?

Divide by 1000 to get seconds, then convert normally. To preserve sub-second precision, use a datetime with microseconds in Python or keep the full millisecond value in JavaScript.

Is Unix time affected by leap seconds?

Officially no — Unix time ignores leap seconds and assumes every day is exactly 86,400 seconds. In practice, systems handle this with "leap smearing" (spreading the extra second over hours) or by simply repeating the last second. For most applications this difference is irrelevant; for high-precision financial or scientific timing, use a proper timescale library.

Cron Syntax Cheat Sheet

All cron patterns and examples on one page — search, copy, use instantly.

Open Cheat Sheet

Convert Timestamps Instantly

Convert Unix timestamps to human-readable dates and back — supports milliseconds, seconds, and all timezones.

Also on MoreOnlineTools