What is a Unix Timestamp? Epoch Time, Y2K38, and How Time Works in Computing
Every time you send a message, make a purchase, or load a webpage, a Unix timestamp records exactly when it happened — a single number counting seconds since January 1, 1970. Understanding how this system works is fundamental to web development, databases, and systems programming.
Table of Contents
What is a Unix Timestamp?
A Unix timestamp (also called Epoch time, POSIX time, or simply Unix time) is the number of seconds that have elapsed since January 1, 1970, at 00:00:00 UTC — a moment known as the Unix Epoch.
For example, the timestamp 1000000000 represents September 9, 2001 at 01:46:40 UTC — exactly one billion seconds after the Epoch. The timestamp 0 is the Epoch itself, and negative timestamps represent dates before January 1, 1970.
This deceptively simple idea — representing time as a single integer — is one of the most important conventions in computing. It's used in virtually every operating system, programming language, database, web API, and log file in existence.
Unix Epoch: January 1, 1970 00:00:00 UTC → 0
1 hour later: January 1, 1970 01:00:00 UTC → 3600
1 day later: January 2, 1970 00:00:00 UTC → 86400
1 year later: January 1, 1971 00:00:00 UTC → 31536000
Today (≈): March 18, 2026 00:00:00 UTC → ~1773964800Why January 1, 1970?
The choice of January 1, 1970 as the Epoch wasn't arbitrary — it was practical. When Unix was being developed at Bell Labs in the late 1960s and early 1970s by Ken Thompson and Dennis Ritchie, they needed a time system for the operating system.
The earliest versions of Unix used a 32-bit integer counting in sixtieths of a second, with an epoch of January 1, 1971. This could only represent about 2.5 years before overflowing. The epoch was reset to January 1, 1970 (a clean, round date) and the resolution was reduced to whole seconds, extending the range to over 136 years — enough to cover dates from 1901 to 2038.
Fun Fact
January 1, 1970 was a Thursday. This means that in Unix time, day 0 is a Thursday, day 4 (Sunday) is the first Sunday, and you can calculate any day of the week by computing (timestamp / 86400 + 4) % 7 (where 0 = Sunday).
How Unix Timestamps Work
At its core, a Unix timestamp is just a counter. Every second, it increases by 1. To convert between a timestamp and a human-readable date, you need to account for years, months (with varying lengths), leap years, and timezone offsets.
Converting timestamp 1234567890 to a date:
Total seconds: 1,234,567,890
÷ 86400 (sec/day): 14,288.98 days
÷ 365.25 (avg): ~39.1 years after 1970
→ February 13, 2009 at 23:31:30 UTC
Converting a date to a timestamp:
March 18, 2026 00:00:00 UTC
= (56 years × 365.25 × 86400) + adjustments
≈ 1,773,964,800
In practice, you use library functions — not manual math!The beauty of this system is that comparing dates becomes simple arithmetic. Is event A before event B? Just compare two integers. How many seconds between them? Subtract. No need to parse date strings or handle different formats.
Seconds vs Milliseconds
One of the most common sources of confusion (and bugs) is the difference between Unix seconds and Unix milliseconds:
| Format | Digits | Example | Used By |
|---|---|---|---|
| Seconds | 10 | 1234567890 | Python, PHP, Ruby, Go, C, Unix CLI, most APIs |
| Milliseconds | 13 | 1234567890000 | JavaScript, Java, Dart, some REST APIs |
| Microseconds | 16 | 1234567890000000 | PostgreSQL, some high-precision systems |
A Classic Bug
If you pass a millisecond timestamp to a function expecting seconds, you'll get a date tens of thousands of years in the future. If you pass seconds where milliseconds are expected, you'll get a date in January 1970. Quick check: if a timestamp has 10 digits, it's seconds. If it has 13 digits, it's milliseconds.
// JavaScript uses milliseconds
Date.now() // 1773964800000 (13 digits)
Math.floor(Date.now() / 1000) // 1773964800 (10 digits, Unix seconds)
// Python uses seconds
import time
time.time() // 1773964800.123 (seconds with decimal)
int(time.time()) // 1773964800 (10 digits)
// Converting between them:
seconds = milliseconds / 1000
milliseconds = seconds * 1000Timestamps and Timezones
One of the greatest strengths of Unix timestamps is that they are timezone-independent. A Unix timestamp represents an absolute moment in time — the same instant everywhere on Earth. The timestamp 1773964800means the same moment whether you're in New York, London, or Tokyo.
Timestamp: 1773964800
UTC (London): March 18, 2026 00:00:00
EST (New York): March 17, 2026 19:00:00 (UTC-5)
JST (Tokyo): March 18, 2026 09:00:00 (UTC+9)
IST (Mumbai): March 18, 2026 05:30:00 (UTC+5:30)
Same instant in time, different local representations.This is why timestamps are preferred over formatted date strings for storage and data exchange. Store the timestamp in your database, and convert to the user's local timezone only when displaying it. This avoids subtle bugs caused by ambiguous date strings like "03/04/2026" (March 4 or April 3?) or daylight saving time transitions.
DST Warning
Daylight Saving Time creates a trap: when clocks "spring forward," one hour disappears (2:00 AM jumps to 3:00 AM). When they "fall back," one hour repeats (1:00 AM happens twice). Timestamps handle this gracefully because they're always in UTC — the wall-clock ambiguity is resolved at display time, not storage time.
Notable Unix Timestamps
Certain Unix timestamps have achieved fame in the developer community for their memorable patterns or historical significance:
| Timestamp | Date (UTC) | Why It's Notable |
|---|---|---|
| 0 | Jan 1, 1970 00:00:00 | The Unix Epoch — where it all began |
| 1000000000 | Sep 9, 2001 01:46:40 | First 10-digit timestamp (1 billion seconds) |
| 1234567890 | Feb 13, 2009 23:31:30 | Sequential digits — celebrated with "Unix time parties" |
| 1500000000 | Jul 14, 2017 02:40:00 | 1.5 billion seconds |
| 2000000000 | May 18, 2033 03:33:20 | 2 billion seconds (coming soon) |
| 2147483647 | Jan 19, 2038 03:14:07 | Maximum 32-bit signed integer — the Y2K38 deadline |
Unix Billennium
When the Unix timestamp hit 1,000,000,000 on September 9, 2001, developers celebrated the "Unix billennium" — the moment Unix time entered the billions. Some held countdown parties, similar to Y2K celebrations.
The Year 2038 Problem (Y2K38)
The Year 2038 problem is the Unix equivalent of the Y2K bug — and it's potentially more dangerous. Many systems store Unix timestamps as signed 32-bit integers, which can hold a maximum value of 2,147,483,647.
This maximum value corresponds to January 19, 2038 at 03:14:07 UTC. One second later, the integer overflows and wraps around to -2,147,483,648, which represents December 13, 1901. Any system still using 32-bit timestamps will suddenly think it's 1901.
32-bit signed integer range:
Min: -2,147,483,648 → Dec 13, 1901 20:45:52 UTC
Max: 2,147,483,647 → Jan 19, 2038 03:14:07 UTC
What happens at 03:14:08 UTC on Jan 19, 2038:
Expected: 2,147,483,648 (needs 33 bits)
Actual: -2,147,483,648 (integer overflow!)
Interpreted as: December 13, 1901
64-bit signed integer range:
Max: 9,223,372,036,854,775,807
→ approximately 292 billion years from now
→ The Sun will have died billions of years before this overflowsWhat's at Risk?
Modern desktop and server operating systems have largely moved to 64-bit timestamps. The real risk lies in embedded systems— IoT devices, car computers, industrial controllers, medical equipment, and legacy file formats that still use 32-bit time. Many of these devices can't be easily updated and may be in service for decades.
The Linux kernel completed its transition to 64-bit timestamps for 32-bit architectures in version 5.6 (2020). Most modern programming languages — JavaScript, Python 3, Go, Rust — natively use 64-bit (or larger) time representations. However, C programs, older databases, and embedded firmware may still need updates.
Timestamps in Every Language
Every major programming language has built-in support for Unix timestamps. Here's how to get the current time and convert between timestamps and dates:
JavaScript / TypeScript
// Current timestamp (MILLISECONDS — divide by 1000 for seconds)
Date.now() // 1773964800000
Math.floor(Date.now() / 1000) // 1773964800
// Timestamp → Date
new Date(1773964800 * 1000) // 2026-03-18T00:00:00.000Z
new Date(1773964800000) // Same result (pass ms directly)
// Date → Timestamp
new Date('2026-03-18').getTime() // 1773964800000 (milliseconds)
Math.floor(new Date('2026-03-18').getTime() / 1000) // secondsPython
import time
from datetime import datetime, timezone
# Current timestamp (SECONDS with decimal)
time.time() # 1773964800.123
# Timestamp → Date
datetime.fromtimestamp(1773964800, tz=timezone.utc)
# datetime(2026, 3, 18, 0, 0, tzinfo=timezone.utc)
# Date → Timestamp
dt = datetime(2026, 3, 18, tzinfo=timezone.utc)
dt.timestamp() # 1773964800.0PHP
// Current timestamp (SECONDS)
time() // 1773964800
// Timestamp → Date
date('Y-m-d H:i:s', 1773964800) // "2026-03-18 00:00:00"
// Date → Timestamp
strtotime('2026-03-18') // 1773964800
mktime(0, 0, 0, 3, 18, 2026) // 1773964800SQL (MySQL / PostgreSQL)
-- MySQL
SELECT UNIX_TIMESTAMP(); -- current timestamp
SELECT FROM_UNIXTIME(1773964800); -- → '2026-03-18 00:00:00'
SELECT UNIX_TIMESTAMP('2026-03-18 00:00:00'); -- → 1773964800
-- PostgreSQL
SELECT EXTRACT(EPOCH FROM NOW()); -- current timestamp
SELECT TO_TIMESTAMP(1773964800); -- → '2026-03-18 00:00:00+00'
SELECT EXTRACT(EPOCH FROM '2026-03-18'::timestamp); -- → 1773964800Command Line
# Linux / macOS
date +%s # current timestamp
date -d @1773964800 # timestamp → date
# Windows PowerShell
[DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
[DateTimeOffset]::FromUnixTimeSeconds(1773964800)Common Date Formats
When converting timestamps to human-readable dates, you'll encounter several standard formats:
| Format | Example | Usage |
|---|---|---|
| ISO 8601 | 2026-03-18T00:00:00.000Z | International standard; APIs, JSON, databases |
| RFC 2822 | Wed, 18 Mar 2026 00:00:00 +0000 | Email headers, HTTP headers |
| RFC 3339 | 2026-03-18T00:00:00Z | Subset of ISO 8601; used in APIs |
| Unix seconds | 1773964800 | Databases, server logs, APIs |
| Relative | 3 days ago | User-facing display (social media, comments) |
Always Use ISO 8601 for Data Exchange
Formats like 03/04/2026 are ambiguous — is it March 4 (US) or April 3 (Europe)? ISO 8601 (2026-03-04) eliminates this ambiguity and sorts correctly as a string. When in doubt, use ISO 8601 or Unix timestamps.
Real-World Use Cases
Unix timestamps are everywhere in modern technology:
Web APIs & JSON: Most REST and GraphQL APIs return timestamps as Unix integers or ISO 8601 strings. JWT tokens contain iat (issued at) and exp (expires) fields as Unix timestamps.
Databases: Relational databases (MySQL, PostgreSQL) store dates internally as timestamps. NoSQL databases like MongoDB use BSON dates based on millisecond timestamps.
Log Files & Monitoring: System logs, application logs, and monitoring tools (Prometheus, Grafana) use timestamps to correlate events across distributed systems.
Caching & TTL: Cache expiration, cookie expiry times, DNS TTL values, and rate limiting all use Unix timestamps to determine when something should expire.
Version Control: Git stores commit timestamps as Unix seconds with timezone offsets. This allows accurate ordering of commits across distributed repositories.
File Systems: Every file on your computer has timestamps — created, modified, and accessed — typically stored internally as Unix time values.
Common Pitfalls
Working with timestamps seems simple, but there are several traps that catch even experienced developers:
1. Mixing Seconds and Milliseconds
JavaScript's Date.now() returns milliseconds, but Python's time.time() returns seconds. Passing one to the other without conversion gives wildly incorrect dates. Always check: 10 digits = seconds, 13 digits = milliseconds.
2. Ignoring Timezones
The Date constructor in JavaScript uses local time by default. new Date('2026-03-18') may give different timestamps on computers in different timezones. Always be explicit: use UTC methods or include timezone info in date strings.
3. Assuming Months are 1-Indexed
JavaScript months are 0-indexed (January = 0, December = 11), while most other languages use 1-indexed months. new Date(2026, 3, 18) is April 18, not March 18!
4. Storing Formatted Strings Instead of Timestamps
Storing dates as strings like "March 18, 2026" makes sorting, comparison, and timezone conversion difficult. Store Unix timestamps or ISO 8601 strings, and format for display only at the application layer.
5. Leap Second Confusion
Unix time does not count leap seconds — every day is exactly 86,400 seconds. This means Unix timestamps diverge very slightly from UTC (by about 27 seconds as of 2024). For virtually all applications, this difference is irrelevant.
Best Practices
Follow these guidelines when working with timestamps in your applications:
- Store in UTC: Always store timestamps in UTC. Convert to local time only when displaying to users.
- Use 64-bit integers: Ensure your language, database, and framework use 64-bit time representations to avoid the Year 2038 problem.
- Document your units: Make it clear whether a field contains seconds or milliseconds. Name fields explicitly:
created_at_msvscreated_at. - Use ISO 8601 for APIs: When timestamps need to be human-readable in APIs, use ISO 8601 format with timezone offset or Z (Zulu/UTC).
- Handle edge cases: Account for negative timestamps (dates before 1970), timestamps at midnight (beginning vs end of day), and timezone boundaries.
- Use libraries: Don't do manual date math. Use battle-tested libraries like Luxon, Day.js, or date-fns (JavaScript), or datetime (Python) for complex date operations.
Convert Unix Timestamps Instantly
Use our free Unix Timestamp Converter to convert between timestamps and human-readable dates. Live timestamp display, 8 output formats, relative time, and timezone-aware conversions — all in your browser.
Try Unix Timestamp Converter →References
- The Open Group. The Open Group Base Specifications Issue 7 — General Concepts: Seconds Since the Epoch. https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html
- Klyne, G. & Newman, C. (2002). Date and Time on the Internet: Timestamps. RFC 3339, IETF. https://datatracker.ietf.org/doc/html/rfc3339
- ISO. ISO 8601: Date and time — Representations for information interchange. https://www.iso.org/iso-8601-date-and-time-format.html
- Mozilla Developer Network. Date - JavaScript. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date