The One Thing Most Developers Get Wrong
The most common Unix timestamp bug is a silent one: JavaScript's Date.now() returns milliseconds, while Python's time.time() returns seconds. Pass a JavaScript timestamp to a Python function expecting seconds and you'll get a date in the year 33658. It's a mismatch that never throws an error — it just silently corrupts your data.
This guide covers every common timestamp operation with copy-paste code in both languages.
What Is a Unix Timestamp?
A Unix timestamp is the number of seconds (or milliseconds) elapsed since January 1, 1970 00:00:00 UTC — the Unix epoch. It has no timezone. It doesn't represent a local time. It's a single integer that means the same thing on every computer in the world.
Current timestamp: you can check it live with the Unix Timestamp Converter.
JavaScript: Timestamps in Milliseconds
// Get current timestamp (milliseconds)
const nowMs = Date.now(); // e.g. 1717200000000
const nowMs2 = new Date().getTime(); // same thing
// Get current timestamp (seconds — for APIs expecting Unix time)
const nowSec = Math.floor(Date.now() / 1000); // e.g. 1717200000
// Convert timestamp to Date object
const date = new Date(1717200000000); // pass milliseconds
console.log(date.toISOString()); // "2024-06-01T00:00:00.000Z"
// Convert seconds timestamp to Date (multiply by 1000 first!)
const fromSeconds = new Date(1717200000 * 1000);
// Date to timestamp (milliseconds)
const ts = new Date('2024-06-01').getTime(); // 1717200000000
// Date to timestamp (seconds)
const tsSec = Math.floor(new Date('2024-06-01').getTime() / 1000);
Python: Timestamps in Seconds (Floats)
import time
import datetime
# Get current timestamp (seconds, float)
now_sec = time.time() # e.g. 1717200000.123
now_int = int(time.time()) # integer seconds
# Convert timestamp to datetime (UTC)
dt_utc = datetime.datetime.fromtimestamp(1717200000, tz=datetime.timezone.utc)
print(dt_utc.isoformat()) # "2024-06-01T00:00:00+00:00"
# Convert timestamp to local datetime (careful with DST)
dt_local = datetime.datetime.fromtimestamp(1717200000)
# Uses system timezone — can behave differently on different machines
# datetime to timestamp
dt = datetime.datetime(2024, 6, 1, tzinfo=datetime.timezone.utc)
ts = dt.timestamp() # 1717200000.0
# Current UTC datetime to timestamp
ts_now = datetime.datetime.now(datetime.timezone.utc).timestamp()
The Milliseconds vs Seconds Problem
| Language/Platform | Unit | Example value |
|---|---|---|
JavaScript Date.now() |
Milliseconds | 1717200000000 |
JavaScript Date.getTime() |
Milliseconds | 1717200000000 |
Python time.time() |
Seconds (float) | 1717200000.0 |
Python datetime.timestamp() |
Seconds (float) | 1717200000.0 |
Unix shell date +%s |
Seconds | 1717200000 |
MySQL UNIX_TIMESTAMP() |
Seconds | 1717200000 |
Java System.currentTimeMillis() |
Milliseconds | 1717200000000 |
Go time.Now().Unix() |
Seconds | 1717200000 |
Go time.Now().UnixMilli() |
Milliseconds | 1717200000000 |
Rule of thumb: If your timestamp is a 13-digit number, it's milliseconds. If it's 10 digits, it's seconds.
// Detect and normalize in JavaScript
function toMilliseconds(ts) {
// If timestamp looks like seconds (10 digits), convert to ms
if (ts < 1e12) return ts * 1000;
return ts;
}
Working with Timezones
Unix timestamps are timezone-agnostic. The complexity comes when converting them to human-readable dates.
// JavaScript — display in specific timezone
const ts = 1717200000000;
const date = new Date(ts);
// UTC
date.toISOString(); // "2024-06-01T00:00:00.000Z"
// User's local timezone
date.toLocaleString(); // varies by system
// Specific timezone (Intl API)
date.toLocaleString('en-US', { timeZone: 'America/New_York' });
// "5/31/2024, 8:00:00 PM"
date.toLocaleString('en-US', { timeZone: 'Asia/Shanghai' });
// "6/1/2024, 8:00:00 AM"
# Python — timezone-aware conversion
import datetime
ts = 1717200000
# Always use UTC explicitly — never rely on system timezone in server code
utc = datetime.timezone.utc
dt_utc = datetime.datetime.fromtimestamp(ts, tz=utc)
# Convert to specific timezone (requires zoneinfo, Python 3.9+)
from zoneinfo import ZoneInfo
dt_ny = dt_utc.astimezone(ZoneInfo('America/New_York'))
print(dt_ny.isoformat()) # "2024-05-31T20:00:00-04:00"
Calculating Time Differences
// JavaScript — time since an event
const eventTs = 1717200000000; // ms
const now = Date.now();
const diffSeconds = Math.floor((now - eventTs) / 1000);
const diffMinutes = Math.floor(diffSeconds / 60);
const diffHours = Math.floor(diffMinutes / 60);
const diffDays = Math.floor(diffHours / 24);
// Is a token expired?
function isExpired(expiryTimestampSeconds) {
return Math.floor(Date.now() / 1000) > expiryTimestampSeconds;
}
# Python — time differences
import time
import datetime
ts1 = 1717200000
ts2 = time.time()
diff_seconds = ts2 - ts1
diff_days = diff_seconds / 86400
# timedelta for readable diffs
dt1 = datetime.datetime.fromtimestamp(ts1, tz=datetime.timezone.utc)
dt2 = datetime.datetime.now(datetime.timezone.utc)
delta = dt2 - dt1
print(delta.days, "days,", delta.seconds // 3600, "hours")
Common Gotchas
Storing timestamps as integers vs strings: Store as integers in your database, not strings. Comparing 1717200000 as a string gives lexicographic ordering, not chronological.
Daylight saving time (DST): A day is not always 86400 seconds when you cross a DST boundary in local time. Always do time arithmetic in UTC timestamps, then format for display.
Year 2038 problem: 32-bit signed integers overflow at Unix timestamp 2147483647 (January 19, 2038). If you're storing timestamps in 32-bit INT columns in older databases, migrate to 64-bit BIGINT now.
Microseconds in Python: time.time() returns a float with sub-second precision. Use int(time.time()) if you need a clean integer seconds value.
→ Convert any Unix timestamp to a human-readable date instantly with the Unix Timestamp Converter.