What Is a Unix Timestamp?
A Unix timestamp โ also called epoch time, POSIX time, or Unix time โ is the number of seconds (or milliseconds) that have elapsed since 00:00:00 UTC on Thursday, January 1, 1970. That specific moment is called the Unix epoch.
For example, the timestamp 1719532800 represents:
1,719,532,800 seconds after January 1, 1970, 00:00:00 UTC
= June 28, 2024, 00:00:00 UTC
Unix timestamps are timezone-agnostic. They always count from the same fixed point in UTC, which makes them the most reliable way to store and exchange dates across different systems, languages, and timezones.
Why January 1, 1970?
The Unix operating system was developed at Bell Labs in the late 1960s and early 1970s. When the designers chose a reference point for their time system, January 1, 1970 was a convenient, recent date. There was no deep technical reason โ it was simply a round number that predated the system's earliest deployments by a comfortable margin.
Alternative epochs exist in other systems:
- Windows FILETIME: 100-nanosecond intervals since January 1, 1601
- Apple Cocoa/Swift: seconds since January 1, 2001
- GPS time: seconds since January 6, 1980
- NTP: seconds since January 1, 1900
Unix time became the global standard for interoperability because Unix and its descendants (Linux, macOS, iOS, Android) power most of the internet's infrastructure.
Seconds vs. Milliseconds vs. Microseconds
This is the most common source of confusion when working with timestamps.
| Unit | Typical Length | Example |
|---|---|---|
| Seconds | 10 digits | 1719532800 |
| Milliseconds | 13 digits | 1719532800000 |
| Microseconds | 16 digits | 1719532800000000 |
| Nanoseconds | 19 digits | 1719532800000000000 |
JavaScript uses milliseconds. Date.now() and new Date().getTime() return milliseconds. If you see a 13-digit timestamp, divide by 1000 to get seconds.
Most Unix tools use seconds. The time system call, date +%s, database TIMESTAMP columns, and most APIs use seconds.
A quick rule of thumb: if the number is 10 digits, it is probably seconds. If it is 13 digits, it is probably milliseconds.
How to Get the Current Unix Timestamp
JavaScript / Node.js
// Milliseconds
const ms = Date.now();
// Seconds
const seconds = Math.floor(Date.now() / 1000);
// Also valid:
const seconds2 = Math.floor(new Date().getTime() / 1000);
Python
import time
# Seconds (float)
t = time.time() # e.g. 1719532800.123
# Seconds (integer)
t = int(time.time()) # e.g. 1719532800
# Milliseconds
import datetime
ms = int(datetime.datetime.now(datetime.timezone.utc).timestamp() * 1000)
Go
import "time"
// Seconds
t := time.Now().Unix()
// Milliseconds
ms := time.Now().UnixMilli()
// Nanoseconds
ns := time.Now().UnixNano()
Bash / Terminal
date +%s # seconds since epoch
date +%s%3N # milliseconds (Linux)
SQL
-- PostgreSQL
SELECT EXTRACT(EPOCH FROM NOW())::INTEGER;
-- MySQL
SELECT UNIX_TIMESTAMP();
-- SQLite
SELECT strftime('%s', 'now');
Converting a Unix Timestamp to a Human-Readable Date
JavaScript
const ts = 1719532800;
// From seconds:
const date = new Date(ts * 1000);
console.log(date.toISOString()); // "2024-06-28T00:00:00.000Z"
console.log(date.toLocaleDateString()); // Locale-dependent
// From milliseconds:
const dateMs = new Date(1719532800000);
Python
import datetime
ts = 1719532800
# UTC
dt = datetime.datetime.fromtimestamp(ts, tz=datetime.timezone.utc)
print(dt.isoformat()) # 2024-06-28T00:00:00+00:00
# Local time
dt_local = datetime.datetime.fromtimestamp(ts)
print(dt_local)
Go
import (
"fmt"
"time"
)
ts := int64(1719532800)
t := time.Unix(ts, 0).UTC()
fmt.Println(t.Format(time.RFC3339)) // 2024-06-28T00:00:00Z
Terminal
# Linux
date -d @1719532800
# macOS
date -r 1719532800
Converting a Date to a Unix Timestamp
JavaScript
// From a date string (UTC)
const ts = Math.floor(new Date('2024-06-28T00:00:00Z').getTime() / 1000);
// From date components (be careful โ month is 0-indexed)
const ts2 = Math.floor(new Date(2024, 5, 28, 0, 0, 0).getTime() / 1000);
// Month 5 = June
Python
import datetime, calendar
dt = datetime.datetime(2024, 6, 28, 0, 0, 0, tzinfo=datetime.timezone.utc)
ts = int(dt.timestamp())
# or
ts = calendar.timegm(dt.timetuple()) # safe UTC conversion
Timezone Gotchas
This is where most timestamp bugs live.
Unix timestamps are always UTC. When you convert 1719532800 to a date, the result depends on your local timezone offset:
- UTC:
2024-06-28 00:00:00 - UTC+5:30 (IST):
2024-06-28 05:30:00 - UTC-7 (PDT):
2024-06-27 17:00:00
This means that the same timestamp represents different calendar dates in different timezones. June 28 in UTC is still June 27 in Los Angeles.
Best practices:
- Store timestamps in UTC. Always.
- Convert to local time only at the point of display.
- In JavaScript, use
.toISOString()(UTC) orIntl.DateTimeFormatwith an explicit timezone for display. - In Python, always use timezone-aware
datetimeobjects. Naive datetimes (notzinfo) silently assume local time and cause bugs.
The Year 2038 Problem
Unix timestamps stored as 32-bit signed integers can represent dates up to January 19, 2038, at 03:14:07 UTC. After that point, the integer overflows from the maximum value (2,147,483,647) to a large negative number, which many systems would interpret as December 1901.
This is the Unix equivalent of Y2K. The fix is straightforward: use 64-bit integers for timestamps, which can represent dates billions of years into the future. Most modern systems already do this. The risk remains in legacy embedded systems and older 32-bit applications that have not been updated.
When to Use Unix Timestamps
Use a Unix timestamp when:
- Storing dates in a database and you need to sort or compare efficiently. Integer comparisons are faster than string comparisons.
- Passing dates between services in an API. JSON has no native date type; a timestamp integer is unambiguous.
- Calculating time differences.
end_ts - start_tsgives you seconds elapsed โ no date parsing needed. - Working across timezones. The timestamp is always UTC; display conversion happens at the client.
Use an ISO 8601 string (2024-06-28T00:00:00Z) when:
- The value needs to be human-readable in logs, config files, or error messages.
- You are storing data in a format where humans might inspect it directly.
- The recipient system expects a date string (many calendar APIs, HTML
<input type="date">, etc.).
Quick Reference: Common Timestamps
| Unix Timestamp | Date (UTC) |
|---|---|
0 |
Jan 1, 1970, 00:00:00 |
86400 |
Jan 2, 1970 (exactly 1 day = 86,400 seconds) |
1000000000 |
Sep 9, 2001, 01:46:40 |
1700000000 |
Nov 14, 2023, 22:13:20 |
2000000000 |
May 18, 2033, 03:33:20 |
2147483647 |
Jan 19, 2038, 03:14:07 (32-bit max) |
Frequently Asked Questions
What is the difference between epoch time and Unix time? They are the same thing. "Epoch time" refers to the concept of counting from a fixed epoch. "Unix time" specifies that the epoch is January 1, 1970, 00:00:00 UTC as defined by the POSIX standard.
Does Unix time count leap seconds? No. Unix time pretends every day has exactly 86,400 seconds. Leap seconds are silently omitted, which means Unix time is not perfectly continuous. For most applications this is irrelevant, but it matters for precision timing in science and telecommunications.
Why does new Date(timestamp) give a different date than I expected?
You probably passed seconds to a JavaScript Date constructor. JavaScript expects milliseconds. Multiply seconds by 1000: new Date(ts * 1000).
How do I store timestamps in MySQL?
Use the DATETIME or TIMESTAMP column types. TIMESTAMP stores as UTC and converts to the server timezone on retrieval. DATETIME stores exactly as given with no timezone conversion. For new projects, store as a BIGINT (milliseconds) if you need sub-second precision or explicit control.
Convert any timestamp to a readable date instantly with the Timestamp Converter โ paste in an epoch value and see the UTC and local date, or pick a date to get the timestamp back.