What Is a Unix Timestamp?

A Unix timestamp is an integer representing the number of seconds elapsed since January 1, 1970 00:00:00 UTC — a reference point known as the "Epoch." For example, 1711756800 represents March 30, 2024 00:00:00 UTC.

Defined by the POSIX standard (IEEE Std 1003.1), this system is the de facto standard for representing time across operating systems, databases, and programming languages. Because timestamps are timezone-independent absolute values, they are ideal for synchronizing time across systems in different time zones.

The Y2K38 Problem

The maximum value of a 32-bit signed integer is 2,147,483,647. Systems that store Unix timestamps as 32-bit integers will overflow at January 19, 2038, 03:14:07 UTC. At that point, the counter rolls over to a negative value and the system behaves as if the date has jumped back to December 13, 1901.

Affected systems include 32-bit Unix/Linux environments (embedded systems, legacy servers), MySQL's TIMESTAMP data type (stored as 32-bit, limited to year 2038), and some legacy PHP environments running on 32-bit systems.

Modern 64-bit operating systems and programming languages already use 64-bit integers for timestamps, so there is no practical risk. The concern is limited to legacy databases still using 32-bit TIMESTAMP columns and embedded systems.

-- Problem: TIMESTAMP limited to 2038
CREATE TABLE events (created_at TIMESTAMP);

-- Solution: Use DATETIME (64-bit, supports up to year 9999)
CREATE TABLE events (created_at DATETIME(3)); -- with milliseconds

Milliseconds vs Seconds

While Unix timestamps are traditionally in seconds, modern systems often use milliseconds — and mixing them up is a common source of bugs.

Key differences by environment: JavaScript's Date.now() returns milliseconds. Python's time.time() returns seconds (as a float). Go's time.Now().Unix() returns seconds; time.Now().UnixMilli() returns milliseconds. Unix shell's date +%s returns seconds.

A quick rule of thumb: a 10-digit value is in seconds, a 13-digit value is in milliseconds. After September 9, 2001, second-based timestamps are always 10 digits.

Timezone Handling

A Unix timestamp is a UTC absolute value — timezone-independent by definition. However, timezone handling becomes critical when converting to human-readable date/time strings.

JavaScript pitfall: A Date object stores UTC internally, but methods like toString() and toLocaleString() output in the browser's local timezone. When server and client are in different timezones, this causes confusion. Use Intl.DateTimeFormat with an explicit timeZone option, or toISOString() to always get a UTC string.

Best practice for databases: Store all times in UTC and convert to the user's timezone at display time. This is especially important for services targeting countries with Daylight Saving Time (DST).

Unix Timestamp vs ISO 8601

Unix timestamps are simple integers — easy to compare and sort, small to store, and timezone-independent. ISO 8601 (2024-01-01T00:00:00Z) is human-readable and can embed timezone information within the string itself, making it the preferred format for API responses and log files.

Best practice: use Unix timestamps for internal storage and calculations; use ISO 8601 for API responses and user-facing output.

Language Examples

JavaScript: Current timestamp in seconds: Math.floor(Date.now() / 1000). Timestamp to Date: new Date(timestamp * 1000). To ISO string: new Date(timestamp * 1000).toISOString().

Python: import time; time.time() for current timestamp. datetime.fromtimestamp(ts, tz=timezone.utc) for UTC conversion.

Go: time.Now().Unix() for seconds. time.Unix(ts, 0) to convert back.

FAQ

What does a negative Unix timestamp mean?

It represents a date before January 1, 1970. For example, -86400 is December 31, 1969. On 64-bit systems, negative timestamps are handled correctly.

Why does mixing Date.now() and Unix timestamps cause bugs?

Date.now() returns milliseconds (13 digits) while Unix timestamps are in seconds (10 digits). Storing a Date.now() value directly in a database TIMESTAMP column — or passing a Unix timestamp directly to a Date constructor — will produce dates off by decades. Always convert: Math.floor(Date.now() / 1000) for seconds, new Date(unixTs * 1000) for the reverse.

Do I need to worry about Y2K38 right now?

For new projects: use 64-bit integers and DATETIME types from the start. For existing projects: audit MySQL TIMESTAMP columns, 32-bit PHP environments, and embedded systems first. 64-bit Linux and modern language runtimes are already safe.

Try the Tool

To instantly convert Unix timestamps to human-readable dates — and vice versa — use the Timestamp Converter. See the current timestamp in real time alongside UTC, local time, and ISO 8601 formats.