Convert epoch timestamp to human time — and back
Unix epoch timestamps are everywhere — log files, databases, API responses, server timestamps. They're integers (seconds since January 1, 1970 UTC). To make them human-readable, you convert to date/time format. The math is straightforward, the edge cases are subtle.
For instant conversion in the browser, the epoch converter handles both directions.
The basic conversion
Epoch to date:
1. Take the epoch timestamp (e.g., 1747842600)
2. Multiply by 1 if seconds, or 1 if already in seconds (no change)
3. Convert to date in UTC:
- This represents "X seconds after January 1, 1970 UTC"
- 1747842600 seconds = ~55.4 years = around May 21, 2026
Date to epoch:
1. Take the date (e.g., May 21, 2026 14:30 UTC)
2. Compute seconds since January 1, 1970 UTC
3. Result is the epoch number (e.g., 1747842600)
Quick reference table
Some specific epoch values:
| Epoch (seconds) | UTC date |
|-----------------|----------|
| 0 | 1970-01-01 00:00:00 |
| 86,400 | 1970-01-02 00:00:00 |
| 946,684,800 | 2000-01-01 00:00:00 |
| 1,000,000,000 | 2001-09-09 01:46:40 |
| 1,500,000,000 | 2017-07-14 02:40:00 |
| 1,704,067,200 | 2024-01-01 00:00:00 |
| 1,747,842,600 | 2026-05-21 14:30:00 (approximate) |
| 2,147,483,647 | 2038-01-19 03:14:07 (32-bit overflow) |
10-digit number = seconds since 1970. 13-digit number = milliseconds (used in JavaScript).
Seconds vs milliseconds
A common confusion. Some systems use seconds, others use milliseconds.
| Format | Bytes | Example | Range to 2038 |
|--------|-------|---------|---------------|
| Unix seconds | 4-8 | 1747842600 | 2,147,483,647 |
| Unix milliseconds | 8 | 1747842600123 | 2,147,483,647,000 |
JavaScript's `Date.now()` returns milliseconds. Most languages' default is seconds.
The epoch converter auto-detects: paste a number, it figures out the format.
Conversion formulas
Manual conversion (epoch to date)
```
epoch_seconds = 1747842600
// Convert to days, hours, minutes, seconds since epoch
days = epoch_seconds / 86400
hourswithinday = (epoch_seconds % 86400) / 3600
minuteswithinhour = (epoch_seconds % 3600) / 60
secondswithinminute = epoch_seconds % 60
// Then convert days to a calendar date
// (handle leap years, month boundaries, etc. — non-trivial)
```
In practice, never compute this manually. Every language has built-in support.
Built-in language support
```python
Python
from datetime import datetime, timezone
dt = datetime.fromtimestamp(1747842600, tz=timezone.utc)
Returns: datetime(2026, 5, 21, ...)
```
```javascript
// JavaScript
const dt = new Date(1747842600 * 1000);
// JavaScript needs milliseconds
dt.toISOString(); // "2026-05-21T14:30:00.000Z"
```
```ruby
Ruby
Time.at(1747842600).utc
Returns: 2026-05-21 14:30:00 UTC
```
```go
// Go
import "time"
t := time.Unix(1747842600, 0).UTC()
// Returns: 2026-05-21 14:30:00 +0000 UTC
```
```sql
-- PostgreSQL
SELECT to_timestamp(1747842600);
-- Returns: 2026-05-21 14:30:00+00
```
Time zone considerations
Epoch is UTC. Always. The number doesn't depend on your zone.
Display can be local. After converting to a date, you can format in any zone:
```python
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
epoch = 1747842600
utc_dt = datetime.fromtimestamp(epoch, tz=timezone.utc)
print(utc_dt) # 2026-05-21 14:30:00+00:00
Convert to specific zone
nydt = utcdt.astimezone(ZoneInfo("America/New_York"))
print(ny_dt) # 2026-05-21 10:30:00-04:00 (EDT)
```
The epoch number is identical across zones. The display varies.
Common scenarios
Reading a log file
Logs often look like:
```
[2026-05-21T14:30:00.000Z] INFO Service started
or
[1747842600] INFO Service started
```
The first format is human-readable. The second is epoch seconds. Convert manually or use the epoch converter.
Database queries
```sql
-- Find events in the last hour
SELECT * FROM events
WHERE epoch_timestamp > EXTRACT(EPOCH FROM NOW()) - 3600;
-- Convert epoch to readable date
SELECT totimestamp(epochtimestamp) AT TIME ZONE 'America/New_York'
FROM events;
```
API responses
```json
{
"user_id": 123,
"created_at": 1747842600,
"last_login": 1747939200
}
```
The numbers are epochs. Convert in your client code or via the epoch converter.
URL parameters
Some APIs use epoch in query params:
```
GET /events?since=1747842600&until=1747939200
```
Same as above — these are epochs. Convert as needed.
Edge cases
Negative epoch (pre-1970)
Negative numbers are valid. -86400 = December 31, 1969 UTC.
Most tools handle this; some legacy code doesn't. Check before relying on negative epoch.
Future dates
Epoch time grows forever. May 21, 2026 = ~1,748 million. May 21, 2050 = ~2,536 million. May 21, 2100 = ~4,118 million.
Modern 64-bit timestamps handle this for billions of years.
The 2038 overflow
For 32-bit signed integers:
- Max value: 2,147,483,647 (= January 19, 2038)
- Beyond that: overflow, returns negative number
Modern systems use 64-bit time. Some legacy systems are vulnerable.
Leap seconds
POSIX time ignores leap seconds. UTC has had 27 leap seconds added since 1972. So a Unix timestamp at "midnight UTC" is technically 27 seconds ahead of true atomic time.
For 99% of uses, ignore this.
Time zones in stored timestamps
If your database column is `timestamp` (without zone) instead of `timestamptz`:
- The stored value is "wall-clock," not absolute UTC
- Converting to epoch loses the zone information
- This is a common source of bugs
Use `timestamptz` for production code.
Tools
Web-based:
- The epoch converter — clean and quick
- timestampgenerator.com
- timestamp-converter.com
Phone apps:
- Various dedicated apps; usually overkill
- iOS Shortcuts can convert with custom workflow
Command line:
```bash
Linux/macOS
date -r 1747842600 # macOS
date -d @1747842600 # Linux
Get current epoch
date +%s
```
Why epochs are useful
Despite the abstraction, epochs are the right way to store timestamps:
Sortable: integers compare correctly chronologically.
Unambiguous: no time-zone confusion. UTC is implicit.
Compact: 4 or 8 bytes vs 20+ bytes for ISO 8601 strings.
Universal: every language supports them.
Arithmetic-friendly: comparing two timestamps is integer subtraction.
For storage, prefer epochs. For display, convert to ISO 8601 or local time.
FAQ
Why is epoch time UTC?
Because that's how Unix defined it in 1970. The Unix designers picked UTC (then called GMT) as the reference. The convention stuck.
What if my timestamp is in milliseconds, not seconds?
Divide by 1000 to get seconds. Or use a tool that auto-detects (the epoch converter does).
Can epochs be negative?
Yes — represents dates before January 1, 1970. The integer is just the count of seconds, with negative meaning "before."
How precise are epochs?
Standard is whole seconds. Some systems use nanoseconds (very precise) or just integer seconds.
Are epochs always positive?
In code today, mostly yes (post-1970 dates). Negative epochs are valid but unusual.
Why don't I just store ISO 8601 strings?
Bytes count for huge tables. Strings are 20+ characters; integers are 4-8 bytes. For 100M rows, this is ~150 MB of difference. Plus integer arithmetic is faster than string parsing.
Bottom line
Unix epoch timestamps (integer seconds since January 1, 1970 UTC) are the standard for time storage in programming. Convert to/from human-readable dates using built-in language support or the epoch converter. 10-digit numbers are seconds; 13-digit numbers are milliseconds.