Understanding Unix Timestamps

A comprehensive guide to Unix timestamps: what they are, how they handle time zones, the Year 2038 problem, and how to work with them in JavaScript, Python, and Bash.

What Is a Unix Timestamp?

A Unix timestamp, also known as Epoch time or POSIX time, is a way of representing a specific moment in time as a single number. It counts the number of seconds that have elapsed since a fixed reference point: January 1, 1970 at 00:00:00 Coordinated Universal Time (UTC). This reference point is called the Unix epoch.

For example, the timestamp 1700000000 represents November 14, 2023 at 22:13:20 UTC. The timestamp 0 represents the epoch itself, and negative values represent dates before 1970. The timestamp -86400, for instance, represents December 31, 1969.

Unix timestamps are the backbone of timekeeping in software development. They appear in databases, log files, API responses, authentication tokens, cron jobs, and just about every system that needs to record when something happened. Their popularity comes from a key property: they are a single integer with no formatting, no timezone, and no ambiguity. This makes them trivially easy to store, compare, sort, and transmit.

The Epoch: January 1, 1970

The choice of January 1, 1970 as the starting point was a pragmatic decision by the early Unix developers at Bell Labs. The original Unix system used a 32-bit counter that incremented every sixtieth of a second. When the counter was later changed to count whole seconds, the engineers needed a recent-enough date that the 32-bit range would cover a useful span of time. January 1, 1970 was a round, convenient choice that provided coverage well into the 21st century.

It is worth noting that the Unix epoch is not the only epoch in computing. Windows FILETIME uses January 1, 1601. Apple's Core Data uses January 1, 2001. GPS time starts on January 6, 1980. When working across systems, always verify which epoch a given timestamp is relative to.

How Unix Timestamps Handle Time Zones

One of the most important characteristics of Unix timestamps is that they are timezone-independent. The value 1700000000 refers to the exact same instant no matter where you are in the world. There is no timezone offset baked into the number itself.

Time zones only matter when you display a timestamp as a human-readable date. The same timestamp will appear as 10:13 PM in London (UTC), 5:13 PM in New York (EST), and 7:13 AM the next day in Tokyo (JST). The underlying integer never changes -- only its presentation does.

This property makes Unix timestamps ideal for distributed systems. When a server in Frankfurt logs an event and a server in Sydney reads that log, there is zero ambiguity about when the event occurred. You never need to worry about daylight saving transitions, UTC offsets, or timezone database updates when storing timestamps. Those concerns only arise at the presentation layer, when you convert the timestamp to a locale-specific string for a user to read.

Second vs. Millisecond Timestamps

Traditional Unix timestamps count seconds since the epoch and are typically 10 digits long (for dates in the current era). However, many modern platforms use millisecond timestamps, which are 13 digits long. JavaScript's Date.now() and Java's System.currentTimeMillis() both return milliseconds by default.

The distinction matters because mixing up seconds and milliseconds is a common source of bugs. If you accidentally treat a millisecond timestamp as seconds, your date will be tens of thousands of years in the future. Conversely, treating a second timestamp as milliseconds will give you a date in January 1970, just hours after the epoch.

Converting between the two is straightforward: multiply seconds by 1,000 to get milliseconds, or divide milliseconds by 1,000 (using integer division) to get seconds. A quick heuristic: if the number has 10 digits, it is almost certainly seconds; if it has 13 digits, it is milliseconds. Some APIs also use microseconds (16 digits) or nanoseconds (19 digits).

The Year 2038 Problem

The Year 2038 problem, sometimes called Y2K38, is a known limitation of systems that store Unix timestamps as a signed 32-bit integer. A signed 32-bit integer can hold a maximum value of 2,147,483,647, which corresponds to January 19, 2038 at 03:14:07 UTC. One second later, the integer overflows, wrapping around to the most negative value and causing the date to jump back to December 13, 1901.

This is analogous to the Y2K bug but potentially more dangerous because timestamps are deeply embedded in file systems, network protocols, database schemas, and kernel-level code. Most modern 64-bit operating systems, programming languages, and databases have already moved to 64-bit timestamps, which will not overflow for approximately 292 billion years. However, embedded systems, IoT devices, and legacy codebases running 32-bit software remain at risk and will need to be updated before 2038.

Working with Timestamps: Code Examples

JavaScript

JavaScript natively works with millisecond timestamps. Use Date.now() to get the current time or divide by 1,000 for a second-precision value.

// Get the current Unix timestamp in seconds
const timestampSec = Math.floor(Date.now() / 1000);
console.log(timestampSec); // e.g. 1712836800

// Convert a timestamp to a human-readable date
const date = new Date(1700000000 * 1000);
console.log(date.toISOString());     // "2023-11-14T22:13:20.000Z"
console.log(date.toLocaleString());  // locale-specific output

// Convert a Date object back to a timestamp
const ts = Math.floor(new Date("2026-04-11T00:00:00Z").getTime() / 1000);
console.log(ts); // 1776124800

Python

Python's time and datetime modules both support Unix timestamps natively.

import time
from datetime import datetime, timezone

# Get the current Unix timestamp in seconds
timestamp = int(time.time())
print(timestamp)  # e.g. 1712836800

# Convert a timestamp to a datetime object (UTC)
dt = datetime.fromtimestamp(1700000000, tz=timezone.utc)
print(dt.isoformat())  # 2023-11-14T22:13:20+00:00

# Convert a datetime back to a timestamp
dt2 = datetime(2026, 4, 11, tzinfo=timezone.utc)
print(int(dt2.timestamp()))  # 1776124800

Bash

The date command on Linux and macOS can convert between timestamps and formatted dates directly from the terminal.

# Get the current Unix timestamp
date +%s
# e.g. 1712836800

# Convert a timestamp to a readable date (GNU/Linux)
date -d @1700000000
# Tue Nov 14 22:13:20 UTC 2023

# Convert a timestamp to a readable date (macOS)
date -r 1700000000
# Tue Nov 14 22:13:20 UTC 2023

# Convert a date string to a timestamp (GNU/Linux)
date -d "2026-04-11T00:00:00Z" +%s
# 1776124800

Try It Yourself

Now that you understand how Unix timestamps work, put your knowledge into practice with our free browser-based tool. No data is sent to any server -- everything runs locally in your browser.

  1. Open the Timestamp Converter tool.
  2. Enter any Unix timestamp (seconds or milliseconds) and instantly see the corresponding date in UTC, local time, ISO 8601, and relative format.
  3. Pick a date and time to convert in the other direction and get the timestamp value.
  4. Use the live clock to grab the current timestamp with a single click.

Frequently Asked Questions

What is the Unix epoch?

The Unix epoch is the fixed reference point from which all Unix timestamps are counted. It is defined as January 1, 1970 at 00:00:00 UTC. Every Unix timestamp is simply the number of seconds (or milliseconds) that have passed since this moment. The epoch was chosen by early Unix developers at Bell Labs as a practical starting date that, combined with a 32-bit counter, would cover a useful range of years.

Do Unix timestamps account for time zones?

No. Unix timestamps are inherently timezone-independent. A given timestamp always represents the same absolute instant everywhere on Earth. Time zones only come into play when you convert a timestamp to a human-readable date string. The same timestamp will display as different local times in New York, London, and Tokyo, but the underlying number never changes. This makes timestamps ideal for storing and transmitting time data across distributed systems.

What is the Year 2038 problem?

The Year 2038 problem (Y2K38) is a computing limitation that affects systems storing Unix timestamps as a signed 32-bit integer. The maximum value such an integer can hold is 2,147,483,647, which corresponds to January 19, 2038 at 03:14:07 UTC. After that second, the value overflows and wraps to a large negative number, causing affected systems to interpret the date as December 13, 1901. Most modern platforms use 64-bit integers to avoid this, but legacy and embedded systems may still be at risk.