timestamper.online

Unix Timestamp: Seconds vs Milliseconds vs Nanoseconds

Last updated 2025-09-10

A practical guide to detect timestamp precision, convert correctly, and avoid real-world pitfalls (JS Date, Python, timezones, DST).

Quick Reference
How to identify and convert timestamp precision
  • 10 digits → seconds, e.g. 1640995200
  • 13 digits → milliseconds, e.g. 1640995200000
  • 19 digits → nanoseconds (as integer), e.g. 1640995200000000000
  • Milliseconds = seconds × 1000; Nanoseconds = seconds × 1,000,000,000
  • JS Date expects milliseconds. Python/UNIX epoch functions often expect seconds.
Detection & Conversion
Robust rules and examples in JavaScript and Python

JavaScript (Node/Browser)

function detectPrecision(x) {
  const s = String(Math.abs(Number(x)));
  if (s.length >= 19) return 'ns';
  if (s.length >= 13) return 'ms';
  if (s.length >= 10) return 's';
  return 'unknown';
}

function toDate(input) {
  const n = Number(input);
  const p = detectPrecision(n);
  if (p === 'ns') return new Date(Math.floor(n / 1e6)); // ns -> ms -> Date
  if (p === 'ms') return new Date(n);
  if (p === 's') return new Date(n * 1000);
  throw new Error('Unsupported timestamp');
}

// Example
const tsS  = 1640995200;        // s
const tsMs = 1640995200000;     // ms
const tsNs = 1640995200000000000n; // ns as BigInt

console.log(toDate(tsS).toISOString());
console.log(toDate(tsMs).toISOString());
console.log(new Date(Number(tsNs / 1000000n)).toISOString());

Python

import datetime

def detect_precision(x: int) -> str:
    s = str(abs(int(x)))
    if len(s) >= 19:
        return 'ns'
    if len(s) >= 13:
        return 'ms'
    if len(s) >= 10:
        return 's'
    return 'unknown'


def to_datetime(x: int) -> datetime.datetime:
    p = detect_precision(x)
    if p == 'ns':
        return datetime.datetime.utcfromtimestamp(x / 1_000_000_000)
    if p == 'ms':
        return datetime.datetime.utcfromtimestamp(x / 1000)
    if p == 's':
        return datetime.datetime.utcfromtimestamp(x)
    raise ValueError('Unsupported timestamp')

print(to_datetime(1640995200).isoformat() + 'Z')          # seconds
print(to_datetime(1640995200000).isoformat() + 'Z')       # milliseconds
print(to_datetime(1640995200000000000).isoformat() + 'Z') # nanoseconds
Common Pitfalls
Real issues that break production systems
  • Milliseconds vs seconds confusion: Passing seconds to JS Date (expects ms) yields 1970 dates.
  • BigInt vs Number: Nanosecond values overflow JS Number (53-bit). Use BigInt and downscale carefully.
  • Timezone assumptions: Timestamps are UTC. Convert to local only for display; store UTC.
  • DST surprises: Local times shift; the timestamp itself does not. Prefer UTC for storage/logic.
  • String parsing: Trim whitespace and validate digits; reject mixed characters.
  • Rounding: When dividing ms→s or ns→s, use floor for consistency with epoch semantics.
FAQs
Quick answers

How do I detect if a value is seconds or milliseconds?

Count digits: 10→seconds, 13→milliseconds. When unsure, compare against current time ranges.

How to convert nanoseconds to ISO date in JavaScript?

Use BigInt division: new Date(Number(BigInt(ns) / 1000000n)).toISOString().

Is it safe to store local time?

Store UTC timestamps; convert for display. Local time storage causes DST/offset bugs.