Why this page
You often get timestamps in seconds (10 digits), milliseconds (13), microseconds (16), or nanoseconds (19). This page gives you one-stop rules, ready-to-ship snippets, and CTAs to the full converter so you can turn any epoch into ISO 8601 / RFC 3339 without guessing the precision.
Quick start (MVP flow)
- Paste the timestamp (we auto-detect length and precision).
- Choose timezone:
UTCor custom offset (e.g.,UTC+08:00). - Get ISO 8601 / RFC 3339 output, then one-click copy.
- Need to embed? Copy a language snippet below.
Try the interactive tool: Timestamp → ISO Converter and Format Builder.
Input rules and validation
- Length detection: 10=seconds, 13=ms, 16=µs, 19=ns.
- Allowed chars: digits only; reject whitespace and letters.
- Range: must be within platform-safe bounds (check 32-bit vs 64-bit; see FAQ).
- Timezone: default UTC; custom offsets like
+08:00,-05:30. - DST: the output uses offset-aware ISO 8601; UTC avoids DST surprises.
Code snippets
JavaScript / Node.js
JAVASCRIPT1const detectPrecision = (raw) => { 2 const len = raw.length; 3 if (len === 10) return { value: Number(raw) * 1000, unit: "ms" }; 4 if (len === 13) return { value: Number(raw), unit: "ms" }; 5 if (len === 16) return { value: Number(raw) / 1000, unit: "ms" }; // µs → ms 6 if (len === 19) return { value: Number(raw) / 1_000_000, unit: "ms" }; // ns → ms 7 throw new Error("Invalid length"); 8}; 9 10const toIso = (raw, tz = "UTC") => { 11 const { value } = detectPrecision(raw); 12 // If you need a fixed offset, use luxon or temporal; here we show UTC 13 return new Date(value).toISOString(); // RFC 3339 compliant 14}; 15 16console.log(toIso("1704067200")); // 10 digits -> seconds 17console.log(toIso("1704067200000")); // 13 digits -> milliseconds
Python
PYTHON1from datetime import datetime, timezone, timedelta 2 3def to_iso(raw: str, offset_minutes: int = 0) -> str: 4 length = len(raw) 5 if length == 10: 6 ts = int(raw) 7 elif length == 13: 8 ts = int(raw) / 1000 9 elif length == 16: 10 ts = int(raw) / 1_000_000 11 elif length == 19: 12 ts = int(raw) / 1_000_000_000 13 else: 14 raise ValueError("Invalid length") 15 16 tz = timezone(timedelta(minutes=offset_minutes)) 17 return datetime.fromtimestamp(ts, tz=tz).isoformat() 18 19print(to_iso("1704067200", 0)) # UTC 20print(to_iso("1704067200000", 480)) # UTC+08:00
Go
GO1package main 2 3import ( 4 "fmt" 5 "time" 6) 7 8func parseEpoch(raw string) (time.Time, error) { 9 switch len(raw) { 10 case 10: 11 sec, _ := time.ParseInt(raw, 10, 64) 12 return time.Unix(sec, 0).UTC(), nil 13 case 13: 14 ms, _ := time.ParseInt(raw, 10, 64) 15 return time.Unix(0, ms*int64(time.Millisecond)).UTC(), nil 16 case 16: 17 us, _ := time.ParseInt(raw, 10, 64) 18 return time.Unix(0, us*int64(time.Microsecond)).UTC(), nil 19 case 19: 20 ns, _ := time.ParseInt(raw, 10, 64) 21 return time.Unix(0, ns).UTC(), nil 22 default: 23 return time.Time{}, fmt.Errorf("invalid length") 24 } 25} 26 27func main() { 28 t, err := parseEpoch("1704067200000") 29 if err != nil { 30 panic(err) 31 } 32 fmt.Println(t.Format(time.RFC3339)) 33}
Common pitfalls
- Wrong precision: 13-digit JS timestamps treated as seconds = huge future date.
- Missing offset: local parsing without specifying timezone yields machine-local time.
- DST edges: if you must show local time, pick a real IANA zone (e.g.,
America/New_York) rather than a fixed offset. - Overflow: 32-bit systems will break after 2038 for second-level timestamps; prefer 64-bit.
FAQ
- Q: Seconds vs milliseconds—how do I tell?
A: Check digit length; if uncertain, run both and see which is in a plausible date window. - Q: Does ISO 8601 require
Z?
A:Zmeans UTC. Any offset like+08:00is also valid ISO 8601 / RFC 3339. - Q: Can I batch convert?
A: Use Batch Timestamp Converter.