Unix Timestamp Explained (Epoch, Seconds & 2038)
By AZ Utils Editorial · · 12 min read
Look closely at a database row, an API response, a log line or a JWT, and you will keep finding the same thing where a date should be: a long number like 1700000000. That number is a Unix timestamp, the way computers have represented moments in time for over half a century. This guide explains exactly what a Unix timestamp is, why it works the way it does, how to read and produce one, and the handful of gotchas that cause real bugs.
It is written for developers and engineers who handle dates in code, students learning how computers represent time, and technical beginners who keep meeting these mysterious numbers.
What Is a Unix Timestamp?
A Unix timestamp is a single number that represents a point in time as the count of seconds elapsed since the Unix epoch — the moment 00:00:00 UTC on 1 January 1970. So a timestamp of 0 is that exact instant, 1 is one second later, and 1700000000 is roughly 1.7 billion seconds after 1970, which lands in November 2023.
The appeal is its sheer simplicity. Instead of juggling years, months, days, hours, minutes, seconds, time zones and calendar quirks, a Unix timestamp reduces "a moment in time" to one integer. That integer is unambiguous, easy to store, trivial to compare (a larger number is always later), and effortless to do arithmetic with (subtract two timestamps and you get the number of seconds between them). For machines, that is close to the perfect representation of time.
Because it is just a count of seconds from a fixed origin, a Unix timestamp is also time-zone independent. It does not represent "3pm in London" or "10am in New York" — it represents a single objective instant that everyone on Earth experiences at the same time, regardless of their local clock. The human-readable, time-zone-specific version is something you produce from the timestamp when you need to display it.
In short: A Unix timestamp is the number of seconds since 00:00:00 UTC on 1 January 1970 (the Unix epoch). It represents a single, time-zone-independent instant as one integer, which makes it ideal for storing, comparing and calculating with time.
Why 1970? A Little History
The choice of 1 January 1970 is not cosmic; it is practical. The convention comes from the early development of the Unix operating system around 1970, and the engineers simply needed a recent, round starting point for the system clock. The epoch stuck, spread with Unix and C, and became a de facto standard adopted far beyond Unix itself — today it underpins time handling in virtually every operating system, programming language, database and protocol you will touch.
That universality is the real value. Because so much software agrees on the same epoch and the same "seconds since" convention, a timestamp generated on a Linux server, stored in a database, sent through a JSON API and read by a browser all mean exactly the same instant. Few standards in computing are as quietly ubiquitous, or as dependable, as the Unix epoch.
Seconds vs Milliseconds: The Number-One Gotcha
Here is the single most common source of timestamp bugs, so it is worth stating early and clearly. Classic Unix time counts seconds, but many environments — JavaScript most famously — count milliseconds since the same epoch. A milliseconds timestamp is simply the seconds value multiplied by 1000, so it is roughly a thousand times larger.
The practical tell is the length and magnitude of the number. A seconds timestamp for the current era has ten digits (around 1.7 × 109); the milliseconds version has thirteen digits (around 1.7 × 1012). If you feed a milliseconds value into something expecting seconds, you will compute a date roughly fifty thousand years in the future; do the reverse and you land back near 1970. Whenever you move a timestamp between systems, the first question to ask is always: is this seconds or milliseconds?
1700000000 // seconds -> Nov 2023 (10 digits)
1700000000000 // millis -> Nov 2023 (13 digits)
Reading and Producing Timestamps in Code
Every language can generate the current timestamp and convert between timestamps and human dates. Note carefully which unit each one uses.
JavaScript (milliseconds)
// Current time in milliseconds since the epoch
const ms = Date.now(); // e.g. 1700000000000
// Current time in SECONDS (divide by 1000, floor it)
const seconds = Math.floor(Date.now() / 1000);
// Timestamp (seconds) -> human date: multiply back to ms
const date = new Date(1700000000 * 1000);
console.log(date.toISOString()); // "2023-11-14T22:13:20.000Z"
Python (seconds)
import time
from datetime import datetime, timezone
now = time.time() # seconds (a float) since the epoch
now_int = int(now)
# Timestamp -> human date in UTC
dt = datetime.fromtimestamp(1700000000, tz=timezone.utc)
print(dt.isoformat()) # "2023-11-14T22:13:20+00:00"
# Human date -> timestamp
ts = int(datetime(2023, 11, 14, 22, 13, 20, tzinfo=timezone.utc).timestamp())
To convert a value without writing any code, paste it into our Timestamp Converter, which turns a Unix timestamp into a readable date (and back) in your browser.
The Year 2038 Problem
For decades, many systems stored Unix time in a signed 32-bit integer. That type can hold a maximum value of 2,147,483,647 — which, counted as seconds from 1970, runs out at 03:14:07 UTC on 19 January 2038. One second later, a 32-bit counter overflows and wraps around to a large negative number, which software would interpret as a date back in 1901. This is the "Year 2038 problem," the spiritual successor to Y2K.
The fix is straightforward and already widespread: use a 64-bit integer for time, which pushes the limit hundreds of billions of years into the future — far longer than the age of the universe. Modern operating systems, languages and databases overwhelmingly use 64-bit time. The risk today is concentrated in old systems, embedded devices and code that still stores time in a 32-bit field, so when you design storage for timestamps, always choose a 64-bit type.
Negative Timestamps and Dates Before 1970
Because a timestamp is just a count from the epoch, dates before 1 January 1970 are represented with negative numbers. A timestamp of -86400 is exactly one day before the epoch, 31 December 1969. Most date libraries handle negatives correctly, but some older or hand-rolled code assumes timestamps are always positive and breaks on historical dates. If your application deals with birthdates, historical records or anything pre-1970, confirm that your storage and parsing handle negative timestamps.
Try Our Free Timestamp Converter
Reading a ten-digit number as a date in your head is impossible, so keep a converter handy. Our Timestamp Converter turns any Unix timestamp into a human-readable date and back, instantly and privately.
- ✅ Convert Unix timestamp → date, and date → timestamp
- ✅ Handles both seconds and milliseconds
- ✅ Runs in your browser — nothing is uploaded
Why This Representation Won
It is worth appreciating just how much friction the Unix timestamp removes, because that explains its dominance. Human calendar time is genuinely messy: months have different lengths, leap years insert an extra day, time zones shift the clock by whole and half hours, daylight saving moves it twice a year, and the rules for all of this vary by country and change over time as governments legislate. Any system that stores time in human terms inherits every one of these complications. Comparing two human dates, or working out the duration between them, becomes an exercise in calendar arithmetic riddled with edge cases.
A Unix timestamp sidesteps the entire mess by refusing to engage with it. It does not know about months or time zones or daylight saving; it is just a count of seconds from a fixed point. Comparison becomes a numeric greater-than, duration becomes a subtraction, and sorting becomes ordering integers. All the calendar complexity is deferred to a single moment — when you format the timestamp for a human to read — and handled there by a well-tested date library rather than scattered through your code. This separation of concerns, storing time as a simple number and applying human formatting only at the edge, is one of the most valuable patterns in all of software, and the Unix timestamp is its purest expression.
A Note on Precision and Resolution
Although classic Unix time counts whole seconds, many situations need finer resolution, and the same epoch-based idea scales down naturally. Milliseconds, microseconds and nanoseconds are all just the same count measured in smaller units, each a thousand times more granular than the last. A logging system might be content with seconds, an analytics pipeline might want milliseconds to order events that happen close together, and a high-frequency trading or scientific system might demand microsecond or nanosecond precision. The trade-off is range versus resolution within a fixed-size integer: the finer your unit, the larger the number for the same moment, and the sooner you approach the limits of a given integer size. For everyday application work, seconds or milliseconds are almost always the right choice, and you only reach for finer resolution when you genuinely need to distinguish events that occur within the same second.
Where Unix Timestamps Are Used
- Databases store created-at and updated-at times as integers for compact, sortable records.
- APIs send timestamps in JSON because a single number is unambiguous across languages and time zones.
- JWTs express their
iat,nbfandexpclaims as Unix timestamps (in seconds). - Logs and metrics tag every event with a timestamp so they can be ordered and correlated precisely.
- Caching and expiry compare "now" against a stored timestamp to decide whether something is stale.
In every case, the timestamp's job is the same: pin down an instant in a way that any system can store, compare and reason about without ambiguity.
Common Mistakes
- Mixing seconds and milliseconds. The most frequent timestamp bug by far — always confirm the unit before using a value.
- Confusing a timestamp with a local time. A timestamp is a UTC-based instant; the time zone is applied only when you format it for display.
- Storing time in a 32-bit field. This invites the Year 2038 overflow; use 64-bit.
- Assuming timestamps are always positive. Pre-1970 dates are negative.
- Treating timestamps as elapsed real seconds. Unix time ignores leap seconds, a subtlety covered in our Unix Time vs UTC guide.
Timestamps in Everyday Development
Once you are comfortable with the concept, you start to see Unix timestamps everywhere in daily development, and recognising them speeds up your work enormously. When you read a log file and see a ten-digit number prefixing each line, you immediately know it is a seconds timestamp and roughly what era it belongs to. When an API returns "expires": 1700003600, you recognise an expiry instant rather than a mysterious code. When a JWT's exp claim is a number, you know to read it as seconds since 1970 and can tell at a glance whether the token is still valid. This fluency turns timestamps from obstacles into useful signals you can interpret on sight.
The same fluency guides better design decisions. Knowing that a timestamp is the most compact, comparable and unambiguous way to store an instant, you reach for it instinctively when modelling created-at and updated-at fields, scheduling future events, measuring durations, or implementing expiry and caching. You also learn to respect its one boundary: a timestamp is for storage and computation, while humans need a formatted, zone-aware date, so you keep the number internally and format only at the display layer. Internalising this division — integers for machines, formatted dates for people — is one of those small habits that quietly prevents a large share of date-related bugs over the life of a project, and it all begins with truly understanding what that long number means.
Best Practices
- Store time as a 64-bit Unix timestamp (or a proper timestamp type) rather than a formatted string.
- Be explicit about the unit — name variables like
expiresAtSecondsorcreatedAtMsso the unit is never in doubt. - Keep time in UTC internally and convert to local time only at the display layer.
- Use ISO 8601 strings for human-facing or interoperable formats, and integers for storage and computation.
- Lean on well-tested date libraries rather than hand-rolling conversions.
Frequently Asked Questions
What is a Unix timestamp?
A Unix timestamp is the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970, known as the Unix epoch. It represents a single, time-zone-independent instant as one integer.
Why does Unix time start in 1970?
The epoch of 1 January 1970 was chosen as a convenient, recent starting point during the early development of Unix, and the convention spread to become a near-universal standard.
Is a Unix timestamp in seconds or milliseconds?
Classic Unix time is in seconds, but some environments (notably JavaScript) use milliseconds. A current seconds timestamp has about 10 digits; the milliseconds version has about 13. Always confirm the unit.
What is the Year 2038 problem?
Systems that store Unix time in a signed 32-bit integer overflow at 03:14:07 UTC on 19 January 2038, wrapping to a negative number. The fix is to use a 64-bit integer for time.
Can a Unix timestamp be negative?
Yes. Dates before the 1970 epoch are represented as negative numbers — for example, -86400 is one day before the epoch.
Does a Unix timestamp include a time zone?
No. A Unix timestamp is a UTC-based count of seconds and carries no time zone. You apply a time zone only when converting it to a human-readable local time.
How do I convert a Unix timestamp to a date?
Use your language's date library (for example new Date(ts * 1000) in JavaScript or datetime.fromtimestamp in Python), or paste the value into an online timestamp converter for an instant result.
Summary
A Unix timestamp is one of computing's most elegant ideas: represent any instant as a single integer counting seconds from a fixed 1970 origin. That makes time easy to store, compare and calculate with, and — because it is anchored to UTC — unambiguous across the whole world. The pitfalls are few but real: keep seconds and milliseconds straight, remember that the time zone is applied only at display time, use 64-bit storage to dodge the 2038 overflow, and allow for negative values before 1970. Master those, lean on good libraries, and keep a converter close, and the long numbers in your logs and APIs stop being mysterious and start being useful.
The next time a long number appears where a date should be, you will not see a puzzle — you will see an instant, encoded in the simplest possible way, that you can decode, compare and reason about with confidence. That shift in perception, from mysterious code to meaningful signal, is the real reward of understanding the Unix timestamp, and it pays off on practically every project you will ever build.
👉 Convert and explore timestamps with our free tool →
Related Resources
- Timestamp Converter — convert timestamps in your browser
- Unix Time vs UTC — how they relate
- How to Convert Timestamps — practical conversions
- Epoch Time Guide — epochs explained in depth
- Timestamp Debugging Guide — fix common bugs