It's 1770422400. Do you know what time it is?
If you work with APIs, databases, or logs, you deal with Unix epoch timestamps constantly. They're the lingua franca of time in computing. Let's make sure you actually understand them.
What is epoch time?
The Unix epoch is January 1, 1970, 00:00:00 UTC. An epoch timestamp is simply the number of seconds that have elapsed since that moment.
| Timestamp | Date |
| 0 | Jan 1, 1970 00:00:00 UTC |
| 1000000000 | Sep 9, 2001 01:46:40 UTC |
| 1700000000 | Nov 14, 2023 22:13:20 UTC |
| 1770422400 | Feb 7, 2026 08:00:00 UTC |
| 2000000000 | May 18, 2033 03:33:20 UTC |
Negative values represent dates before 1970. For example, -86400 is December 31, 1969.
Why 1970? Unix was being developed at Bell Labs in the late 1960s. The original epoch was January 1, 1971, but it was later moved back to 1970 for a rounder number. The choice was pragmatic, not profound.
Seconds vs. milliseconds: the common trap
This is the single most common source of epoch-related bugs. Some systems use seconds, others use milliseconds.
Seconds: 1770422400
Milliseconds: 1770422400000
If you pass milliseconds to a function expecting seconds, you'll get a date thousands of years in the future. If you pass seconds where milliseconds are expected, you'll get January 1970.
Who uses what:
| System | Unit |
Unix/Linux time() | Seconds |
Python time.time() | Seconds (float) |
JavaScript Date.now() | Milliseconds |
Java System.currentTimeMillis() | Milliseconds |
PostgreSQL EXTRACT(EPOCH FROM ...) | Seconds |
MySQL UNIX_TIMESTAMP() | Seconds |
| API common practice | Usually seconds |
The rule of thumb: if the number is 10 digits, it's seconds. If it's 13 digits, it's milliseconds. In 2026, a seconds timestamp starts with 17, a milliseconds timestamp starts with 177.
Getting the current epoch
JavaScript
// Milliseconds (native)
const ms = Date.now();
console.log(ms); // 1770422400000// Seconds
const sec = Math.floor(Date.now() / 1000);
console.log(sec); // 1770422400
Python
import time
from datetime import datetimeSeconds (float)
epoch = time.time()
print(epoch) # 1770422400.123456Seconds (integer)
epoch_int = int(time.time())
print(epoch_int) # 1770422400
Bash
# Seconds
date +%s
1770422400
Milliseconds (GNU coreutils)
date +%s%3N
1770422400123
macOS (no native milliseconds, use Python)
python3 -c "import time; print(int(time.time() * 1000))"
Go
import "time"// Seconds
epoch := time.Now().Unix()
// Milliseconds
epochMs := time.Now().UnixMilli()
SQL
-- PostgreSQL
SELECT EXTRACT(EPOCH FROM NOW());-- MySQL
SELECT UNIX_TIMESTAMP();
-- SQLite
SELECT strftime('%s', 'now');
Converting epoch to human-readable dates
JavaScript
// From seconds
const date = new Date(1770422400 * 1000); // multiply by 1000!
console.log(date.toISOString());
// "2026-02-07T08:00:00.000Z"console.log(date.toLocaleString('en-US', { timeZone: 'America/New_York' }));
// "2/7/2026, 3:00:00 AM"
Python
from datetime import datetime, timezoneUTC
dt = datetime.fromtimestamp(1770422400, tz=timezone.utc)
print(dt.isoformat())
"2026-02-07T08:00:00+00:00"
Local time
dt_local = datetime.fromtimestamp(1770422400)
print(dt_local)
Bash
# GNU/Linux
date -d @1770422400
Sat Feb 7 08:00:00 UTC 2026
macOS
date -r 1770422400
Converting human-readable dates to epoch
JavaScript
const epoch = Math.floor(new Date('2026-02-07T08:00:00Z').getTime() / 1000);
console.log(epoch); // 1770422400
Python
from datetime import datetime, timezonedt = datetime(2026, 2, 7, 8, 0, 0, tzinfo=timezone.utc)
epoch = int(dt.timestamp())
print(epoch) # 1770422400
Bash
# GNU/Linux
date -d "2026-02-07T08:00:00Z" +%smacOS
date -j -f "%Y-%m-%dT%H:%M:%S" "2026-02-07T08:00:00" +%s
The Y2038 problem
On January 19, 2038, at 03:14:07 UTC, the Unix epoch timestamp will reach 2,147,483,647 -- the maximum value for a signed 32-bit integer. One second later, systems using 32-bit timestamps will overflow, potentially wrapping around to December 13, 1901.
2147483647 → Tue Jan 19 03:14:07 UTC 2038
2147483648 → ??? (overflow on 32-bit systems)
Is this a real problem? For most modern systems, no. 64-bit timestamps have been the default on Linux since the mid-2000s. A signed 64-bit epoch won't overflow until the year 292,277,026,596. Your code will be fine.
But embedded systems, IoT devices, old databases, and some file formats still use 32-bit timestamps. If you're working with any of these, it's worth checking. The Linux kernel completed its internal Y2038 remediation, but userspace code varies.
Epoch timestamps in databases
Storing timestamps
Most databases offer both epoch integers and native timestamp types. Use native types when possible:
-- Prefer this
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()-- Over this
created_at BIGINT DEFAULT EXTRACT(EPOCH FROM NOW())
Native timestamp types give you timezone handling, comparison operators, and date math for free. Epoch integers are useful for interoperability with external systems.
Indexing
Epoch integers are slightly more efficient to index than timestamps, but the difference is negligible for most applications. Don't optimize for this unless you're dealing with billions of rows.
Quick conversions
For quick conversions when you're debugging or reading logs, devdash.io/tools/epoch-converter lets you paste a timestamp and see the human-readable date instantly, or go the other direction. Handy when you're staring at a log full of 1770422400 values and need to know what happened when.
Common patterns
Generate a unique-ish ID:
const id = evt_${Date.now()}_${Math.random().toString(36).slice(2, 7)};
// "evt_1770422400123_k8f2j"
Check if a token is expired:
const isExpired = (exp) => Math.floor(Date.now() / 1000) > exp;
Calculate time ago:
function timeAgo(epochSeconds) {
const diff = Math.floor(Date.now() / 1000) - epochSeconds;
if (diff < 60) return ${diff}s ago;
if (diff < 3600) return ${Math.floor(diff / 60)}m ago;
if (diff < 86400) return ${Math.floor(diff / 3600)}h ago;
return ${Math.floor(diff / 86400)}d ago;
}
Key takeaways
- Epoch time = seconds since January 1, 1970 UTC
- JavaScript uses milliseconds; most other systems use seconds
- 10 digits = seconds, 13 digits = milliseconds
- Always handle timezones explicitly --
fromtimestamp()without a timezone is a bug waiting to happen - Y2038 is real but mostly affects 32-bit embedded systems
- Use native database timestamp types unless you have a specific reason for epoch integers