What Is a Unix Timestamp? A Developer's Guide to Epoch Time

TimeKit ·
#unix timestamp#epoch time#developer tools#timestamp converter

If you have ever looked at a raw API response and seen something like 1719014400, you have encountered a Unix timestamp. It looks like a random number, but it is one of the most important conventions in computing. Every database, every log file, every scheduling system relies on it, usually behind the scenes. Understanding what it is, how it works, and where it breaks will save you hours of debugging.

This guide covers everything a developer needs to know about Unix timestamps, from the basics to the edge cases that cause real bugs.

What Is a Unix Timestamp?

A Unix timestamp (also called Unix epoch time or POSIX time) is the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC — excluding leap seconds. That starting point is called the Unix epoch.

The timestamp 1719014400 means “1,719,014,400 seconds after midnight UTC on January 1, 1970,” which corresponds to June 22, 2024, at 00:00:00 UTC. Every moment in time, past or future, can be expressed as a single integer using this system.

The simplicity is the point. A timestamp is one number. It has no time zone, no daylight saving ambiguity, no formatting variation. It is the same whether you read it in Tokyo, London, or Buenos Aires. This makes it ideal for storage, comparison, and computation.

Why Unix Timestamps Exist

Before Unix timestamps, time representation was a mess. Different systems used different formats. Some stored dates as separate year, month, day, hour, minute, second fields. Others used proprietary encodings. Comparing two timestamps from different systems required parsing both formats and converting them to a common representation.

The Unix timestamp solved this by defining a single, universal format. One integer, one reference point, one rule (count seconds from the epoch). This gives timestamps several properties that make them useful for developers.

Unambiguous. A timestamp represents exactly one moment in time. There is no confusion about time zones or daylight saving, because the epoch is defined in UTC and the count never changes.

Easy to compare. To determine which of two events happened first, compare the integers. No parsing, no date library, no format conversion. A larger number means a later time.

Easy to store. An integer takes less space than a formatted date string. A 32-bit integer can store timestamps up to January 2038. A 64-bit integer can store timestamps for billions of years.

Easy to compute. Adding an hour means adding 3600 to the timestamp. Adding a day means adding 86400. Arithmetic on timestamps is simple integer math.

Seconds vs Milliseconds

Here is a detail that trips up developers regularly: not all systems use seconds.

The original Unix timestamp counts seconds. Most Unix utilities, Linux system calls, and REST APIs use seconds. But JavaScript’s Date.now() returns milliseconds. Java’s System.currentTimeMillis() also returns milliseconds. Python’s time.time() returns seconds (as a float), but some Python libraries expect milliseconds.

This means that if you pass a JavaScript timestamp to an API that expects seconds, the API will interpret it as a date roughly 51,000 years in the future. Conversely, if you pass a seconds timestamp to JavaScript, it will interpret it as a date in January 1970.

The rule of thumb: if the number is 10 digits long, it is probably seconds. If it is 13 digits long, it is probably milliseconds. Always check the documentation for the specific API or library you are using.

Common Pitfalls

The 2038 Problem

A 32-bit signed integer can store values up to 2,147,483,647. This corresponds to January 19, 2038, at 03:14:07 UTC. One second later, the integer overflows and wraps to a negative number, which the system interprets as a date in 1901.

This is the Year 2038 problem, and it is the same class of bug as Y2K. Most modern systems have already migrated to 64-bit timestamps, which can represent dates for 292 billion years. But embedded systems, legacy databases, and old file formats may still use 32-bit timestamps. If you are working with a system that was built before 2010 and has not been updated, check how it stores time.

Timezone Confusion

A Unix timestamp is always UTC. It does not contain timezone information, because it does not need to — it represents an absolute moment. The confusion arises when you convert a timestamp to a human-readable date. The same timestamp produces different local times depending on the timezone of the system doing the conversion.

For example, 1719014400 is June 22, 2024, 00:00:00 UTC. In New York (UTC-4), it is June 21, 2024, 8:00pm. In Tokyo (UTC+9), it is June 22, 2024, 9:00am. The timestamp has not changed. The local representation has.

This causes bugs when developers assume that converting a timestamp to a date string produces the same result on every server. It does not. If your application server is in one timezone and your database is in another, the same timestamp will produce different dates unless you explicitly specify UTC in the conversion.

Leap Seconds

Unix timestamps ignore leap seconds. When a leap second is inserted (which has happened 27 times since 1972), the Unix timestamp repeats the same value for two consecutive seconds. This means that, strictly speaking, you cannot use a Unix timestamp to measure the exact duration between two events that span a leap second.

In practice, this rarely matters. Most applications do not need sub-second precision across leap second boundaries. But if you are building a system that requires precise timekeeping — financial trading, scientific instrumentation, aerospace — you need to be aware of this limitation and use a time standard that accounts for leap seconds, such as TAI (International Atomic Time).

Floating-Point Precision

Some systems store timestamps as floating-point numbers, where the integer part is seconds and the fractional part is sub-seconds. Python’s time.time() works this way. The problem is that floating-point numbers lose precision as the integer part grows. A 64-bit float can represent timestamps with microsecond precision today, but as the timestamp value increases, the precision decreases. For most applications this is fine, but for high-frequency logging or performance measurement, it can cause issues.

How to Convert Timestamps

Converting between Unix timestamps and human-readable dates is something developers do constantly. Here are the common methods.

In the browser, JavaScript provides new Date(timestamp * 1000) for seconds timestamps (multiply by 1000 because JavaScript uses milliseconds) and new Date(timestamp) for millisecond timestamps.

On the command line, date -r 1719014400 on macOS or date -d @1719014400 on Linux converts a timestamp to a local date string.

In Python, datetime.fromtimestamp(1719014400, tz=timezone.utc) converts a timestamp to a UTC datetime object.

In a database, most SQL databases have built-in functions. PostgreSQL uses to_timestamp(1719014400). MySQL uses FROM_UNIXTIME(1719014400).

For quick, one-off conversions without writing code, TimeKit’s epoch converter at /epoch-converter lets you paste a timestamp and instantly see the corresponding date and time in UTC and your local timezone. It also works in reverse: enter a date and time, and it returns the Unix timestamp in both seconds and milliseconds.

Practical Examples

API Debugging

When an API returns unexpected results, the first thing to check is the timestamp. Is it in seconds or milliseconds? Is it in the past or the future? Is the timezone correct? Converting the raw timestamp to a readable date often reveals the problem immediately — a millisecond timestamp being interpreted as seconds, or a UTC timestamp being displayed in local time.

Log Analysis

Server logs almost always use Unix timestamps because they are compact and unambiguous. When you are searching for events in a time range, convert your target dates to timestamps and search the log for entries between those values. This is faster and more reliable than parsing date strings, because string formats vary but timestamps are always the same.

Database Queries

Querying a time-range in a database is simplest when the time column stores timestamps. A query like SELECT * FROM events WHERE created_at > 1719014400 is clear, fast, and timezone-independent. If the column stores formatted dates instead, you need to handle timezone conversion in the query, which is slower and more error-prone.

A Quick Reference

WhatValue
EpochJanuary 1, 1970, 00:00:00 UTC
UnitSeconds (or milliseconds in JavaScript/Java)
10-digit numberSeconds timestamp
13-digit numberMilliseconds timestamp
32-bit overflowJanuary 19, 2038
Leap secondsIgnored in Unix time
TimezoneAlways UTC

Unix timestamps are not glamorous, but they are one of the few conventions in computing that nearly every system agrees on. Understanding how they work — and where they break — is a foundational skill for any developer who works with time, which is to say, every developer.