Epoch Time Cheat Sheet: Seconds, Millis, Micros, Nanos (2026)
Unix timestamps come in seconds, milliseconds, microseconds, and nanoseconds. This 2026 cheat sheet shows how to tell them apart and convert safely.
Epoch Time Cheat Sheet: Seconds, Milliseconds, Microseconds, Nanoseconds
You copy a timestamp from a log line, paste it into a converter, and get a date in 1970 — or 50,000 years out. The number was fine; you guessed its unit wrong. Epoch time counts the time elapsed since January 1, 1970 UTC, but that can be measured in seconds, milliseconds, microseconds, or nanoseconds. This cheat sheet shows how to spot which unit you have and convert without off-by-1000 bugs.
TL;DR
- Epoch time counts from 1970-01-01 00:00 UTC, but the unit is not stored in the number.
- In 2026: seconds are 10 digits, milliseconds 13, microseconds 16, nanoseconds 19.
- JavaScript
Date.now()is milliseconds; most backends and JWTexpuse seconds. - Convert by powers of 1000, and floor before narrowing (ms → s) to avoid surprises.
- Nanosecond values exceed JavaScript's safe integer range — use
BigInt.
How to tell seconds, milliseconds, microseconds, and nanoseconds apart
The single most useful skill here is reading a raw epoch value and knowing its unit at a glance. There is no type tag inside the integer — 1748563200 and 1748563200000 are both just numbers — so the unit lives in your head and in the system that produced the value.
How many digits is a Unix timestamp in 2026?
Count the digits. Because the epoch clock keeps growing, the digit count for "now" is stable for years at a time. A current seconds timestamp passed the 10-digit mark in 2001 (at 1,000,000,000) and stays 10 digits until November 2286. So in 2026 the rule of thumb is simple:
| Unit | Digits (2026) | Example "now" |
|---|---|---|
| Seconds | 10 | 1748563200 |
| Milliseconds | 13 | 1748563200000 |
| Microseconds | 16 | 1748563200000000 |
| Nanoseconds | 19 | 1748563200000000000 |
Each step adds three digits because each is 1000× the previous. If a value has 13 digits and you read it as seconds, you land in the year ~57,000; if it has 10 digits and you read it as milliseconds, you land in early 1970. Both mistakes are instantly visible once you actually format the date — which is why a quick conversion is the best sanity check.
Why a 13-digit timestamp is milliseconds, not seconds
The factor between each unit is exactly 1000, and that compounds. One second is 1000 milliseconds, so a milliseconds timestamp is the seconds value with three more digits glued on the end. This is why JavaScript developers constantly hit the "my timestamp is 1000× too big" bug: per MDN, Date.now() returns the number of milliseconds elapsed since the epoch, while the backend it talks to almost always speaks seconds.
The quick digit-count cheat sheet
When you only need a yes/no answer, this is the whole decision tree:
- 10 digits → seconds. Feed straight into most CLI tools and
date -d @value. - 13 digits → milliseconds. Divide by 1000 for seconds.
- 16 digits → microseconds. Divide by 1,000,000 for seconds.
- 19 digits → nanoseconds. Divide by 1,000,000,000 for seconds.
You can verify any of these in a second with a browser-based Unix timestamp converter — paste the number, see the date, and if it reads 1970 or the far future, you picked the wrong unit.
How to convert between epoch units without bugs
Conversion is multiplication and division by powers of 1000. The bugs come from two places: losing precision when you narrow, and overflowing the number type when you widen.
Seconds to milliseconds and back
Widening is lossless — you are adding zeros:
const seconds = 1748563200;
const millis = seconds * 1000; // 1748563200000
Narrowing is where data disappears. Going from milliseconds to seconds throws away the sub-second part, so decide explicitly whether you want to floor or round:
const millis = 1748563200789;
const seconds = Math.floor(millis / 1000); // 1748563200
Why dividing milliseconds by 1000 truncates
1748563200789 / 1000 is 1748563200.789. If you store that in an integer column or pass it to a function expecting whole seconds, the .789 is silently dropped — and if you used Math.round instead of Math.floor, a value ending in 500 or higher rounds up to the next second. For event ordering and JWT expiry this matters: an exp claim is a whole-seconds epoch value, and rounding it up can extend a token's life by up to a second. When you decode a token to inspect that claim, a JWT decoder shows exp and iat as raw seconds you can convert by hand.
Microseconds and nanoseconds: watch the integer overflow
Microseconds (16 digits) still fit comfortably in a 64-bit integer and in most languages' default number types. Nanoseconds (19 digits) are where JavaScript breaks: a regular JavaScript number is an IEEE-754 double, and integers stay exact only up to Number.MAX_SAFE_INTEGER, which is 9007199254740991 (about 9.0e15, 16 digits). A 2026 nanosecond timestamp is roughly 1.77e18 — three orders of magnitude past that — so the low digits get rounded:
const ns = 1748563200123456789n; // BigInt literal
const seconds = ns / 1000000000n; // 1748563200n
The n suffix makes it a BigInt, which holds arbitrary precision. Without it, the value would be mangled before you ever divided.
Which epoch precision each language gives you
The unit you get back depends entirely on the function you call. Knowing the defaults per language saves you from guessing.
JavaScript: Date.now() is milliseconds
Date.now() and new Date().getTime() both return milliseconds. There is no built-in seconds function, so the idiomatic "epoch seconds" expression is Math.floor(Date.now() / 1000). One subtlety: per MDN, browsers deliberately reduce the precision of Date.now() to resist timing attacks — Firefox rounds to 2 ms by default via privacy.reduceTimerPrecision — so even the millisecond digit is not guaranteed to be exact for fingerprinting-sensitive use.
Python: time.time() vs time.time_ns()
Python's time.time() returns seconds as a float, which is convenient until you need real nanosecond precision. A float can't hold it: PEP 564 explains that the 53-bit mantissa of a double loses resolution once the epoch value grows large, so Python 3.7 added time.time_ns(), which returns an int count of nanoseconds with no float rounding. The rule: use time.time() for human-scale timing and time.time_ns() when you actually need the bottom digits.
Go, Java, and SQL defaults
Go's time package gives you all four explicitly — Unix() for seconds, plus UnixMilli() and UnixMicro() (added in Go 1.17) and UnixNano() — so the unit is right there in the method name; see the Go time package docs. Java's System.currentTimeMillis() returns milliseconds, matching JavaScript. In SQL, Postgres extract(epoch from now()) returns seconds as a numeric with a fractional part, while MySQL UNIX_TIMESTAMP() returns whole seconds — another reason to confirm the unit at every system boundary rather than assume.
When you actually need sub-second precision
Most applications are fine with seconds. Reaching for microseconds or nanoseconds without a reason just inflates storage and invites the overflow bug above.
Logs, APIs, and ordering events
Milliseconds is the practical sweet spot for application logs and web APIs: it's fine-grained enough to order events that happen within the same second, and it stays inside JavaScript's safe integer range. When you're scanning a log file full of raw epoch values, a regex tester helps you pull out the 10- or 13-digit numbers before you batch-convert them.
High-frequency trading and profiling
Microseconds and nanoseconds earn their keep in performance profiling, hardware instrumentation, and high-frequency trading, where two events can legitimately occur within the same millisecond and you still need a stable order. Here the cost of the extra digits is worth it — but you commit to 64-bit integers (or BigInt in JavaScript) throughout the pipeline.
Why nanoseconds break JavaScript numbers
To restate the trap, because it bites people repeatedly: a nanosecond epoch timestamp does not round-trip through a JavaScript number. If a service hands you 1748563200123456789, parsing it with Number() or letting JSON.parse coerce it will quietly corrupt the last few digits. Keep nanosecond values as strings on the wire and convert to BigInt only when you need arithmetic.
References
- Date.now() — MDN Web Docs — confirmed that
Date.now()returns milliseconds since the epoch and the Firefox 2 ms precision reduction. - PEP 564 – Add new time functions with nanosecond resolution — source for why floats lose nanosecond precision and when
time.time_ns()was introduced (Python 3.7). - time package — Go Packages — method names and units for
Unix,UnixMilli,UnixMicro, andUnixNano. - Unix time — Wikipedia — epoch definition (1970-01-01 00:00 UTC) and the digit-count milestones.
Related on iKit
- Unix Timestamp Explained: the 10-digit numbers in your logs — start here if you're staring at a raw epoch value in a log line and need to know what it means before converting it.
- Convert a Unix timestamp to a date without the timezone bug — once you've identified the unit, this covers the other half of the conversion: formatting the instant in the right timezone.
Related posts
Resize Image for Instagram, X & LinkedIn: 2026 Cheatsheet
The exact image dimensions for every Instagram, X, and LinkedIn placement in 2026 — feed, story, header, banner, profile — plus a one-click resize workflow.
Why I Built iKit: 14 Privacy-First Tools That Stay in Your Browser (2026)
iKit is 14 free online tools — none of them upload your files. Here's the story of why I built it that way, and what it means in practice for the people using it.