Unix timestamp converter: seconds, milliseconds, microseconds explained
timestamp unix developer-tools
Unix timestamp converter: seconds, milliseconds, microseconds explained
The Unix timestamp is one of those things that looks simple until you use it across languages and find out that JavaScript expects milliseconds, Python expects seconds, and your database expects something else entirely. This guide explains the three common units, how to convert between them, and the bugs that happen when you get it wrong.
Want to convert a timestamp right now without writing code? Use the free Timestamp Converter — supports seconds, milliseconds, microseconds, and nanoseconds, with timezone-aware output.
What a Unix timestamp is
A Unix timestamp is the number of seconds (or sub-seconds) that have elapsed since 1970-01-01 00:00:00 UTC, excluding leap seconds. This moment is called the Unix epoch.
The timestamp is always UTC. It has no timezone. When you display it as a human-readable date, you apply a timezone — but the timestamp itself is universal.
Three common units:
| Unit | Magnitude | Used by |
| Seconds | 10 digits in 2026 | Python time.time(), C time(), most Unix tools |
| Milliseconds | 13 digits in 2026 | JavaScript Date.now(), Java System.currentTimeMillis() |
| Microseconds | 16 digits in 2026 | Python time.time_ns() / Go time.Now().UnixMicro() |
| Nanoseconds | 19 digits in 2026 | Go time.Now().UnixNano(), Python time.time_ns() |
The rule of thumb: count the digits.
- 10 digits → seconds (e.g.
1751328000= 2026-07-01 00:00:00 UTC) - 13 digits → milliseconds (e.g.
1751328000000) - 16 digits → microseconds
- 19 digits → nanoseconds
new Date(...), you get a date in 1970 — that is bug #1 below.Converting between units
The conversions are powers of 1000:
1 second = 1,000 milliseconds = 1,000,000 microseconds = 1,000,000,000 nanoseconds
Seconds → milliseconds (JS)
const seconds = 1751328000;
const ms = seconds * 1000;
const date = new Date(ms);
Milliseconds → seconds (Python)
import time
ms = 1751328000000
seconds = ms // 1000
Any unit → JS Date
JavaScript Date only accepts milliseconds. Convert first:
function toDate(timestamp, unit) {
const multipliers = {
s: 1000,
ms: 1,
us: 0.001,
ns: 0.000001,
};
return new Date(timestamp * multipliers[unit]);
}
The three classic bugs
Bug 1: Passing seconds to JavaScript Date
new Date(1751328000);
// Thu Jan 21 1970 06:05:28 GMT+0000
JavaScript expects milliseconds. Multiply by 1000:
new Date(1751328000 * 1000);
// Wed Jul 01 2026 00:00:00 GMT+0000
Bug 2: Integer overflow with nanoseconds
JavaScript numbers are 64-bit floats, which can exactly represent integers up to 2^53 (about 9 quadrillion). A nanosecond timestamp in 2026 is around 1.7 trillion — well within range. But if you are doing arithmetic on nanosecond timestamps from multiple sources, you can lose precision.
Fix: use BigInt for nanosecond timestamps:
const ns = 1751328000000000000n;
const ms = Number(ns / 1_000_000n);
new Date(ms);
Bug 3: Timezone confusion when displaying
The timestamp is UTC. When you call toString() on a Date in JavaScript, it uses the runtime's local timezone. The same timestamp prints differently on a server in Tokyo vs a server in New York.
const ts = 1751328000000;
new Date(ts).toString();
// In Tokyo: "Wed Jul 01 2026 09:00:00 GMT+0900"
// In New York: "Tue Jun 30 2026 20:00:00 GMT-0400"
This is correct — the timestamp is the same instant. But if you store the string representation and compare it later, you will get mismatches.
Fix: always store and transmit the numeric timestamp. Only convert to a string at the display layer, using an explicit timezone:
new Date(ts).toLocaleString('en-US', { timeZone: 'America/New_York' });
Or use toISOString() for a canonical UTC string:
new Date(ts).toISOString();
// "2026-07-01T00:00:00.000Z"
Language reference
JavaScript
Date.now(); // milliseconds (number)
new Date().getTime(); // milliseconds (number)
new Date().toISOString(); // "2026-07-01T00:00:00.000Z"
Python
import time
from datetime import datetime, timezonetime.time() # seconds (float)
time.time_ns() # nanoseconds (int)
datetime.now(timezone.utc) # datetime object with tz
datetime.now(timezone.utc).timestamp() # seconds (float)
Go
import "time"time.Now().Unix() // seconds (int64)
time.Now().UnixMilli() // milliseconds (int64)
time.Now().UnixMicro() // microseconds (int64)
time.Now().UnixNano() // nanoseconds (int64)
Java
System.currentTimeMillis(); // milliseconds (long)
Instant.now().getEpochSecond(); // seconds (long)
Instant.now().toEpochMilli(); // milliseconds (long)
SQL
-- Postgres
SELECT EXTRACT(EPOCH FROM NOW()); -- seconds (double precision)
SELECT EXTRACT(EPOCH FROM NOW()) * 1000; -- milliseconds-- MySQL
SELECT UNIX_TIMESTAMP(); -- seconds
SELECT UNIX_TIMESTAMP() * 1000; -- milliseconds (as decimal)
-- SQLite
SELECT strftime('%s', 'now'); -- seconds (text)
Timezones and display
The timestamp is UTC. To show it in a user's local time, you need to know their timezone. In a browser, the default is the user's system timezone:
new Date(1751328000000).toLocaleString();
// Uses the browser's local timezone automatically
On a server, the default is the server's timezone, which is usually not what you want. Always specify:
new Date(1751328000000).toLocaleString('en-US', {
timeZone: 'Asia/Shanghai',
});
For storing timestamps in a database, prefer storing the numeric timestamp (or an ISO 8601 string in UTC). Avoid storing "local time" strings without a timezone offset — you will regret it.
Common conversions
Timestamp → ISO 8601
new Date(1751328000000).toISOString();
// "2026-07-01T00:00:00.000Z"
ISO 8601 → timestamp
Date.parse("2026-07-01T00:00:00.000Z");
// 1751328000000
Timestamp → human-readable
new Date(1751328000000).toLocaleString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZone: 'UTC',
});
// "Wednesday, July 1, 2026 at 12:00:00 AM"
Timestamp → date only
new Date(1751328000000).toISOString().slice(0, 10);
// "2026-07-01"
Edge cases
Leap seconds
Unix timestamps skip leap seconds. When a leap second is inserted, the timestamp counts 23:59:60 and then 23:59:60 again (same timestamp twice). Most systems ignore leap seconds entirely and treat the day as 86401 seconds long with no special handling. This means timestamps across leap-second boundaries are not perfectly precise — but for almost all applications, this does not matter.
Dates before 1970
Negative timestamps work. new Date(-1) is 1969-12-31T23:59:59.999Z. Most languages handle this correctly, but some older systems do not.
Year 2038 problem
A 32-bit signed integer overflows at 2^31 - 1 = 2,147,483,647 seconds, which is 2038-01-19 03:14:07 UTC. Systems still using 32-bit timestamps will break on that date. Modern systems use 64-bit integers and are safe until the year 292 billion.
Try it yourself
Open the free RuMystic Timestamp Converter:
- Auto-detects seconds, milliseconds, microseconds, nanoseconds from the digit count.
- Converts to local time, UTC, and any timezone you pick.
- Bidirectional: type a date, get the timestamp.
- Copy-paste friendly.
- No upload — your input stays in the browser.