Back to Blog

Unix epoch time explained — what it is and why it matters

January 6, 2026
7 min read
Written by ConvertTime Team
epochunix-timedevelopersfundamentals2038

If you've ever seen a number like `1747842600` in a log file, an API response, or a database column, that's Unix epoch time. It's the most boring and most useful timestamp format in computing: an integer that uniquely identifies any moment in history (within a useful range) without any time zone confusion.

The fastest way to convert an epoch number to a human date — or back — is the epoch converter. Paste a number, see the date.

What it is

Unix epoch time is the number of seconds elapsed since 00:00:00 UTC on January 1, 1970. That moment — the "epoch" — is timestamp 0. Everything since then is a positive integer count of seconds.

Some quick reference points:

| Date | Unix epoch (seconds) |
|------|----------------------|
| 1970-01-01 00:00:00 UTC | 0 |
| 2000-01-01 00:00:00 UTC | 946,684,800 |
| 2010-01-01 00:00:00 UTC | 1,262,304,000 |
| 2020-01-01 00:00:00 UTC | 1,577,836,800 |
| 2026-05-10 00:00:00 UTC | 1,778,236,800 (approx.) |
| 2038-01-19 03:14:07 UTC | 2,147,483,647 (the 32-bit overflow) |

Negative epoch values represent dates before 1970 (e.g., -86400 is 1969-12-31 UTC).

Why January 1, 1970?

Because that's roughly when Unix was being designed. Ken Thompson and Dennis Ritchie at Bell Labs needed a reference point for time-stamping files. They picked the start of 1970 partly for the round number, partly because it was about 5 years before the time of writing, and partly because Unix v1 was released in 1971 — so most timestamps in early Unix systems were small positive integers.

There was no deeper philosophical reason. They could have picked 1900, or 1972, or any other date. The choice stuck because Unix spread, and POSIX standardized it.

Why every server uses it

Three properties make Unix epoch the default timestamp for almost all server code:

1. It's a single integer. No "what time zone?" ambiguity, no daylight-saving-time conversion needed. Two epoch timestamps can be compared with a simple integer subtraction. Sorting works. Database indexes are efficient. Arithmetic is just arithmetic.

2. It's always UTC. The Unix epoch is defined as seconds since the 1970 epoch in UTC. It doesn't shift with time zones, daylight saving time, or any other local-time complication. Your server can be in Singapore, your database in Virginia, and your client in Brazil — they all agree on the same epoch number for the same moment.

3. It's universally supported. Every language has a "current epoch time" function. C: `time(NULL)`. Python: `int(time.time())`. JavaScript: `Math.floor(Date.now() / 1000)`. PHP: `time()`. Go: `time.Now().Unix()`. Java: `System.currentTimeMillis() / 1000`.

This is why almost every JSON API response with a timestamp uses epoch — it's the lingua franca.

Seconds vs milliseconds

There's one common gotcha: some systems use seconds, some use milliseconds.

- Seconds since epoch is the original Unix convention. As of 2026, it's a 10-digit number (e.g., `1747842600`).
- Milliseconds since epoch is JavaScript's default (`Date.now()`) and many newer APIs. As of 2026, it's a 13-digit number (e.g., `1747842600123`).

If you see a number that's 13 digits long, it's almost certainly milliseconds. Divide by 1000 to get seconds. The epoch converter handles both.

The Year 2038 problem (Y2K38)

A signed 32-bit integer can hold values from -2,147,483,648 to 2,147,483,647. The maximum positive value, 2,147,483,647, corresponds to January 19, 2038 at 03:14:07 UTC. After that moment, a 32-bit signed timestamp overflows and wraps around to a large negative number — which most software interprets as a date in 1901.

This is the Year 2038 problem, sometimes called Y2K38. It's the same class of issue as Y2K, but with arithmetic overflow rather than 2-digit year encoding.

Most modern software has already migrated to 64-bit timestamps, which extend the usable range to about 292 billion years. But there are still affected systems:

- Embedded systems and IoT devices — many cheap microcontrollers still use 32-bit timestamps in firmware that's hard to update.
- Old database schemas — anywhere a column is `INT` or `INTEGER` (not `BIGINT`) and stores epoch time.
- Legacy file formats — some binary file headers store epoch as 32-bit. Migrating means changing the file format.
- Embedded RTC chips in industrial equipment — controllers that have been in service for 20+ years.

The fix is straightforward (use 64-bit), but the migration is real work that has to happen eventually. Most enterprises with legacy systems are doing this between 2025–2035.

Common operations on epoch time

Get current epoch.
```javascript
// JavaScript
const now = Math.floor(Date.now() / 1000); // seconds
const nowMs = Date.now(); // milliseconds
```
```python

Python


import time
now = int(time.time()) # seconds
```
```bash

Shell


date +%s # seconds
```

Convert epoch to human date.
```javascript
// JavaScript — note Date constructor takes ms
const date = new Date(1747842600 * 1000);
date.toISOString(); // "2026-05-21T..."
```
```python

Python


from datetime import datetime, timezone
datetime.fromtimestamp(1747842600, tz=timezone.utc).isoformat()
```

Time difference.
```javascript
const diffSeconds = epochB - epochA;
const diffMinutes = diffSeconds / 60;
const diffDays = diffSeconds / 86400; // 86400 seconds per day
```

For one-off conversions or sanity checks, the epoch converter is faster than firing up a REPL.

Edge cases that bite

Leap seconds. UTC includes occasional leap seconds (an extra second added to keep UTC within 0.9s of solar time). Strict POSIX timestamps don't include leap seconds — they pretend leap seconds never happened. This means a Unix timestamp can technically have multiple "real" UTC moments mapping to the same number. Most application code doesn't care; financial trading systems and astronomical software do.

Pre-1970 dates. Negative epoch values are valid in the standard, but some old or buggy software treats negative epoch as an error. If you're working with historical dates, test your code with negative timestamps.

The year 1970 vs 1969 boundary. Some older C libraries returned timestamps with subtle bugs near epoch zero (date arithmetic crossing the 1969/1970 boundary). Almost never relevant in modern code, but watch for it in legacy systems.

Time zone in display layer. Epoch is always UTC. When you convert it to a human date for display, you'll usually want to show local time. The conversion happens at the display boundary, not in the database. Most date libraries (Moment.js, date-fns, JavaScript's Intl, Python's pytz/zoneinfo) handle this correctly when you pass the target time zone explicitly.

When NOT to use epoch

Epoch is great for storing timestamps. It's bad for two things:

Storing recurring schedules. If your app needs to send "an email at 9 AM local time every Tuesday," you don't store that as an epoch — you store the rule (`9:00 weekly Tuesday America/New_York`) and let your scheduler compute the next epoch trigger each time. Storing absolute epochs would mean re-computing them every time DST changes, every time the user moves, etc.

Storing wall-clock dates with no time component. "Lisa's birthday is May 21" should be stored as the date `2026-05-21`, not as an epoch like `1747780800` — the epoch implicitly picks midnight UTC, which means in some time zones the date will display as May 20. Use a date type (`DATE` in SQL, or just an ISO date string) for date-only values.

FAQ

What's the difference between Unix time and epoch time?

In casual usage they're the same. "Unix epoch time" is the precise name; "Unix time" or just "epoch" are common abbreviations. All three refer to seconds (or milliseconds) since January 1, 1970 UTC.

Why is the 2038 problem only on 32-bit systems?

The number 2,147,483,647 (the maximum value of a 32-bit signed integer) corresponds to that moment in 2038. A 64-bit signed integer can hold values up to about 9.2 quintillion, which corresponds to roughly 292 billion years from now. So 64-bit timestamps don't have this problem (in any practical sense).

Why does my JavaScript timestamp have 13 digits when Python's has 10?

JavaScript's `Date.now()` returns milliseconds since epoch; Python's `time.time()` returns seconds (as a float, with sub-second precision). To convert: divide JavaScript by 1000, multiply Python by 1000. The epoch converter auto-detects which one you've pasted.

Can epoch time be negative?

Yes. Negative epoch values represent dates before January 1, 1970 UTC. For example, -86,400 is December 31, 1969 UTC.

Is the leap second a problem in practice?

For most software, no. Web servers, mobile apps, databases — they all ignore leap seconds and treat 86,400 seconds per day as a constant. The systems that care are: GPS satellites, financial trading platforms, very precise scientific timekeeping, and astronomy. Most of these have specific leap-second handling code.

How do I count days between two dates using epoch?

`(epochB - epochA) / 86400`, then floor or round depending on whether you want full days. 86,400 is seconds per day. This is exact for UTC; for local time across DST shifts, it's off by an hour twice a year — use a real date library for those cases.

Bottom line

Unix epoch time is the integer count of seconds since January 1, 1970 UTC. It's the universal timestamp format for servers, databases, and APIs because it's unambiguous, sortable, and language-agnostic. The 2038 problem is real but mostly affects legacy systems; modern code uses 64-bit timestamps that won't overflow for billions of years.

For day-to-day conversions, the epoch converter handles seconds, milliseconds, and ISO 8601 strings — paste any of them and it shows the others.

Share this article

Related Articles