Last updated 2025-09-10
A practical guide to detect timestamp precision, convert correctly, and avoid real-world pitfalls (JS Date, Python, timezones, DST).
1640995200
1640995200000
1640995200000000000
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());
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
Date
(expects ms) yields 1970 dates.BigInt
and downscale carefully.Count digits: 10→seconds, 13→milliseconds. When unsure, compare against current time ranges.
Use BigInt division: new Date(Number(BigInt(ns) / 1000000n)).toISOString()
.
Store UTC timestamps; convert for display. Local time storage causes DST/offset bugs.