DevToolbox
All articles

Unix Timestamps Explained: A Developer's Complete Guide

· 6 min read

Open any database schema, read any server log, or inspect any API response and you will encounter Unix timestamps. They look cryptic — 1716239022 means nothing at a glance — but they are the most reliable, timezone-safe way to represent a moment in time in software. This guide explains what Unix timestamps are, how to convert them in every common language, and the pitfalls that trip up developers at every experience level.

What Is the Unix Epoch?

A Unix timestamp (also called epoch time or POSIX time) is the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC. That specific moment is called the Unix epoch, and it is the universal zero point for time in computing.

Why 1970? When the Unix operating system was being developed in the late 1960s, the designers needed a fixed reference point. January 1, 1970 was chosen pragmatically — it was recent enough that the numbers would stay manageable for years. It was not a technically significant date; it simply became the standard through Unix's widespread adoption, and every major language and operating system has honored it since.

The key advantage of Unix timestamps is that they are timezone-agnostic. The value 1716239022 refers to the exact same instant everywhere on Earth. Converting to a human-readable date in a specific timezone is a display concern, not a storage concern — which is exactly the right separation of responsibilities.

Seconds vs. Milliseconds: The Most Common Bug

This is the number one source of timestamp bugs in real applications. The Unix standard uses seconds, but JavaScript's Date object works in milliseconds. The difference is a factor of 1,000.

Pass a seconds-based timestamp directly to new Date() in JavaScript and you will get a date in 1970, not the date you intended. Pass a milliseconds-based timestamp to a Python or Go function expecting seconds and you will get a date tens of thousands of years in the future.

A quick sanity check: a current Unix timestamp in seconds is a 10-digit number (e.g., 1716239022). A millisecond timestamp is 13 digits (e.g., 1716239022000). If your timestamp has more than 10 digits, it is almost certainly in milliseconds.

Converting a Timestamp to a Human Date

JavaScript:

const ts = 1716239022; // seconds

// Multiply by 1000 to convert seconds → milliseconds
const date = new Date(ts * 1000);

console.log(date.toISOString());
// "2024-05-20T18:43:42.000Z"

console.log(date.toLocaleString('en-US', { timeZone: 'America/New_York' }));
// "5/20/2024, 2:43:42 PM"

Python:

from datetime import datetime, timezone

ts = 1716239022

# UTC
dt_utc = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt_utc.isoformat())
# 2024-05-20T18:43:42+00:00

# Local system timezone
dt_local = datetime.fromtimestamp(ts)
print(dt_local)
# depends on the system timezone

Bash / shell:

# macOS / BSD
date -r 1716239022

# Linux (GNU date)
date -d @1716239022

# Output: Mon May 20 18:43:42 UTC 2024

Converting a Human Date to a Timestamp

JavaScript:

// Current timestamp in seconds
const nowSeconds = Math.floor(Date.now() / 1000);

// Specific date to timestamp
const ts = Math.floor(new Date('2024-05-20T18:43:42Z').getTime() / 1000);
console.log(ts); // 1716239022

Python:

from datetime import datetime, timezone

# Current timestamp in seconds
import time
now = int(time.time())

# Specific UTC date to timestamp
dt = datetime(2024, 5, 20, 18, 43, 42, tzinfo=timezone.utc)
ts = int(dt.timestamp())
print(ts)  # 1716239022

Bash:

# macOS / BSD
date -j -f "%Y-%m-%d %H:%M:%S" "2024-05-20 18:43:42" +%s

# Linux (GNU date)
date -d "2024-05-20 18:43:42 UTC" +%s

Timezone Pitfalls

Timestamps themselves have no timezone — they are always UTC offsets from the epoch. The pitfalls arise during conversion.

  • Python's datetime.fromtimestamp() without a timezone uses the local system timezone. On a developer's laptop in EST and a production server in UTC, the same code produces different results. Always pass tz=timezone.utc explicitly, then convert to the desired timezone for display.
  • JavaScript's new Date().toLocaleString() uses the browser's local timezone by default. Always pass the timeZone option explicitly when displaying dates to users in a specific region.
  • Storing timestamps in a database: Store the raw Unix timestamp or a UTC datetime column. Never store a timezone-local string — it creates ambiguity during daylight saving transitions and makes sorting unreliable.
  • Daylight saving time: Because Unix timestamps track UTC seconds continuously, they are immune to DST gaps and overlaps. The complexity only appears at display time, which is the right place for it.

Negative Timestamps: Before 1970

Unix timestamps can be negative. A timestamp of -86400 represents December 31, 1969, 00:00:00 UTC — one day before the epoch. Most modern languages and databases handle negative timestamps correctly, but it is worth testing if your application needs to represent historical dates before 1970 (archival systems, historical records, etc.).

// JavaScript
new Date(-86400 * 1000).toISOString();
// "1969-12-31T00:00:00.000Z"

# Python
datetime.fromtimestamp(-86400, tz=timezone.utc).isoformat()
# '1969-12-31T00:00:00+00:00'

The Year 2038 Problem

On January 19, 2038 at 03:14:07 UTC, 32-bit signed integers used to store Unix timestamps will overflow. A 32-bit signed integer can hold a maximum value of 2,147,483,647, which corresponds exactly to that date. The next second will roll over to -2,147,483,648, which represents December 13, 1901 — a catastrophic regression for any system that uses 32-bit timestamps.

Most modern systems already use 64-bit integers for timestamps, which pushes the overflow problem to the year 292,277,026,596 — safely outside anyone's planning horizon. However, embedded systems, legacy C code, and some older databases may still use 32-bit time representations. If you maintain such systems, auditing for 32-bit timestamp usage is worthwhile before 2038.

Convert Timestamps Instantly Online

For quick conversions during debugging, the DevToolbox Unix Timestamp Converter displays the current timestamp in real time and lets you convert any timestamp to a human-readable date (or vice versa) across multiple timezones. Everything runs in your browser — no server involved.

Summary

Unix timestamps are a count of seconds since January 1, 1970 UTC. They are timezone-agnostic, globally consistent, and easy to compare and sort. The two traps to memorize: JavaScript uses milliseconds (multiply by 1,000 when converting from seconds), and Python's datetime.fromtimestamp() defaults to local time (always pass tz=timezone.utc). Store timestamps in UTC, convert to the user's timezone only at display time, and you will avoid the vast majority of timestamp bugs.

Try it free
Unix Timestamp Converter
100% client-side · no signup · no upload
Open tool →