A Unix timestamp in nanoseconds counts nanoseconds — billionths of a second — since the epoch 1970-01-01T00:00:00Z. This is the resolution used by Go’s time.UnixNano(), many distributed-tracing backends, InfluxDB, high-frequency trading logs, and precision telemetry pipelines. Because a present-day nanosecond value is about 19 digits — well past Number.MAX_SAFE_INTEGER (about 16 digits) — this converter does all arithmetic with JavaScript BigInt to preserve every digit.
How it works
The tool parses the nanosecond input as a BigInt and splits it into two parts: whole milliseconds (which the Date object understands) and the nanosecond remainder within the current second:
const ns = BigInt(input);
const ms = ns / 1_000_000n; // whole milliseconds since epoch
const remNsInSecond = ((ns % 1_000_000_000n) + 1_000_000_000n) % 1_000_000_000n;
const date = new Date(Number(ms)); // calendar date-time
The Date provides the year, month, day, hour, minute, and second. The nanosecond remainder is then zero-padded to 9 digits and appended as the fractional-seconds component of the ISO-8601 output string, so the result captures the full sub-millisecond precision available in the input.
For the reverse direction, the tool parses the ISO date-time to milliseconds using Date.parse() and multiplies by 1_000_000n — producing a nanosecond value whose last six digits are zero, because Date.parse does not capture sub-millisecond input.
How to identify which precision your timestamp is in
Count the digits of the current-era value:
| Digits | Unit | Example |
|---|---|---|
| ~10 | Seconds | 1700000000 |
| ~13 | Milliseconds | 1700000000000 |
| ~16 | Microseconds | 1700000000000000 |
| ~19 | Nanoseconds | 1700000000000000000 |
If your value is 19 digits it is almost certainly nanoseconds. If it is 16, try the microseconds converter first. A 13-digit value should go to the milliseconds converter.
Why JavaScript uses BigInt for nanoseconds
JavaScript’s Number type is a 64-bit IEEE 754 float, which can represent integers exactly only up to Number.MAX_SAFE_INTEGER = 9,007,199,254,740,991 — about 9 quadrillion, or roughly 16 digits. A nanosecond timestamp for dates after approximately 1973 already exceeds 10¹⁶, so storing it in a plain number silently loses precision in the last few digits. BigInt arithmetic operates on the exact integer value with no floating-point rounding, so 1700000000123456789n stays exactly that — the three sub-microsecond digits at the end are preserved, not silently zeroed.
Systems that emit nanosecond timestamps
- Go:
time.Now().UnixNano()returns anint64of nanoseconds since epoch. Goroutine timestamps and span durations in OpenTelemetry traces typically use this. - InfluxDB: the database stores time with nanosecond resolution; its line protocol timestamp field is epoch nanoseconds.
- Linux kernel:
clock_gettime(CLOCK_REALTIME, &ts)fills astruct timespecwith seconds and nanoseconds separately; multiplyingts.tv_sec * 1e9 + ts.tv_nsecgives the nanosecond epoch. - Prometheus: internally uses milliseconds (not nanoseconds), but many scrape targets report timestamps in nanoseconds in their exposition format.
- Kafka: message timestamps are in milliseconds, not nanoseconds — use the milliseconds converter for Kafka offsets.
Practical notes
- Because browser
Date.parseonly resolves to milliseconds, encoding a calendar date to nanoseconds will always give a value ending in six zeros — sub-millisecond input from the date picker is not possible. - The fractional-seconds field in the output always shows 9 digits so you can verify which sub-second digits your input actually carries.
- All computation runs locally in your browser using BigInt. Nothing is uploaded.