How to convert timestamps (seconds vs milliseconds) without messing it up
Snippets to detect unit by length and convert to UTC ISO. Includes timezone notes and common pitfalls (1970 / year 51382).
Use this article when...
This section is built for speed: one concrete task, multiple stacks, and the minimum context needed not to copy the wrong thing.
Work from the request or response body that actually failed instead of rebuilding JSON from memory.
The useful path here is fast adaptation: choose your stack, then copy only after reading the notes around parsing and formatting.
Once the snippet runs, inspect the live payload with JSON Formatter or the related tool to confirm the structure is really fixed.
What this article gives you
A short path from incident to implementation: context, language-specific snippets, and the warning signs that usually get skipped.
13
3
timestamps, dates, debugging, backend, frontend
The most common timestamp bug is mixing units: JavaScript uses milliseconds, but many backends (and JWT exp) use seconds. Result: 1970 dates or absurd far-future years.
Practical rule: 10 digits ≈ seconds; 13 digits ≈ milliseconds. Normalize internally (e.g. ms) and convert at the boundaries.
Dependency snapshot by language
Check this first to see which snippets use built-in/runtime APIs and which ones need external packages before you start copying code.
Review the notes for setup details.
Built-in or runtime API
Review the notes for setup details.
Built-in or runtime API
Review the notes for setup details.
Built-in or runtime API
Review the notes for setup details.
Built-in or runtime API
Built-in or runtime API
Built-in or runtime API
chrono = "0.4".
Built-in or runtime API
Built-in or runtime API
How to use these code examples well
The snippet is only the fast path. The explanation and notes are what keep you from copying the wrong assumption into production.
Make sure the article really matches the issue you are debugging before copying code just because the title looks close.
That is where portability limits, dependency requirements, and runtime assumptions usually appear.
If the code runs but the bug remains, jump to the related tool and inspect the real payload, token, timestamp, or config.
Code examples by language
Snippets that compile/run, plus short explanations and real-world notes.
Bash
ts="1711022400000"
if [ ${#ts} -ge 13 ]; then sec=$((ts/1000)); else sec=$ts; fi
if date --version >/dev/null 2>&1; then
date -u -d "@$sec" +"%Y-%m-%dT%H:%M:%SZ"
else
date -u -r "$sec" +"%Y-%m-%dT%H:%M:%SZ"
fi
Detects ms vs s by length, normalizes to seconds, and uses date in UTC to print ISO. Useful for quick debugging.
- Works with GNU date and BSD date (macOS).
- If your timestamp is a string with spaces, trim it first.
C#
using System;
var ts = "1711022400000";
var n = long.Parse(ts);
var ms = ts.Length >= 13 ? n : n * 1000;
var iso = DateTimeOffset.FromUnixTimeMilliseconds(ms).ToUniversalTime().ToString("o");
Console.WriteLine(iso);
Normalize to milliseconds and use DateTimeOffset.FromUnixTimeMilliseconds to get a UTC ISO string (o format).
- Std.
- If input can be invalid, catch FormatException/OverflowException.
Delphi
program TimestampToIso;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
System.DateUtils;
var
Ts: string;
N: Int64;
Sec: Int64;
Dt: TDateTime;
begin
Ts := "1711022400000";
N := StrToInt64(Ts);
if Length(Ts) >= 13 then
Sec := N div 1000
else
Sec := N;
Dt := UnixToDateTime(Sec, True);
Writeln(DateToISO8601(Dt, True));
end.
Converts to seconds when the input is milliseconds and uses UnixToDateTime(..., True) as UTC. DateToISO8601 returns an ISO string.
- Std: System.DateUtils.
- To show local time, convert to local timezone before formatting.
Go
package main
import (
"fmt"
"time"
)
func main() {
ts := "1711022400000"
var n int64
fmt.Sscan(ts, &n)
var ms int64
if len(ts) >= 13 {
ms = n
} else {
ms = n * 1000
}
t := time.Unix(0, ms*int64(time.Millisecond)).UTC()
fmt.Println(t.Format(time.RFC3339))
}
Normalize to milliseconds and build a time.Time using nanoseconds. Then print RFC3339 in UTC.
- Std.
- If parsing from string, handle errors in production.
Java
import java.time.Instant;
public class Main {
public static void main(String[] args) {
String ts = "1711022400000";
long n = Long.parseLong(ts);
long ms = ts.length() >= 13 ? n : n * 1000;
System.out.println(Instant.ofEpochMilli(ms).toString());
}
}
Instant.ofEpochMilli is the modern java.time approach. It prints ISO-8601 in UTC.
- Std (Java 8+).
JavaScript
const ts = "1711022400000";
const n = Number(ts);
const ms = ts.length >= 13 ? n : n * 1000;
console.log(new Date(ms).toISOString());
JS Date works in milliseconds. Normalize to ms and use toISOString() for UTC.
- Std.
- If numbers get huge, watch precision (Number is float).
Kotlin
import java.time.Instant
fun main() {
val ts = "1711022400000"
val n = ts.toLong()
val ms = if (ts.length >= 13) n else n * 1000
println(Instant.ofEpochMilli(ms).toString())
}
In Kotlin/JVM you can use Instant (java.time) just like in Java.
- Std (JVM).
PHP
<?php
$ts = "1711022400000";
$n = (int)$ts;
$ms = strlen($ts) >= 13 ? $n : $n * 1000;
$sec = (int) floor($ms / 1000);
$dt = (new DateTimeImmutable("@" . $sec))->setTimezone(new DateTimeZone("UTC"));
echo $dt->format(DATE_ATOM) . PHP_EOL;
Normalize to ms, convert to seconds for DateTimeImmutable epoch constructor, and force UTC with DateTimeZone.
- Std.
- If your timestamp comes as float/decimals, normalize first.
Python
from datetime import datetime, timezone
ts = "1711022400000"
n = int(ts)
ms = n if len(ts) >= 13 else n * 1000
sec = ms / 1000
print(datetime.fromtimestamp(sec, tz=timezone.utc).isoformat())
Convert to seconds (float) and create a UTC datetime. isoformat() outputs ISO for logs.
- Std.
- In production, store UTC and convert at the UI if needed.
Ruby
require "time"
ts = "1711022400000"
n = ts.to_i
sec = ts.length >= 13 ? (n.to_f / 1000) : n
puts Time.at(sec).utc.iso8601(3)
Normalize to seconds and use Time.at(...).utc.iso8601 to get a UTC timestamp.
- Std.
- This example preserves milliseconds when they are present in the input.
Rust
use chrono::{TimeZone, Utc};
fn main() {
let ts = "1711022400000";
let n: i64 = ts.parse().unwrap();
let dt = if ts.len() >= 13 {
Utc.timestamp_millis_opt(n).single().unwrap()
} else {
Utc.timestamp_opt(n, 0).single().unwrap()
};
println!("{}", dt.to_rfc3339());
}
With chrono, convert to seconds and create a DateTime<Utc>. to_rfc3339 outputs an ISO string with timezone.
- Dependency: chrono = "0.4".
TypeScript
const ts = "1711022400000";
const n = Number(ts);
const ms = ts.length >= 13 ? n : n * 1000;
console.log(new Date(ms).toISOString());
In TS/JS the trick is the same: Date uses ms. Use toISOString() for UTC.
- Std.
- For precision and safety, avoid Number in backends when handling huge ints.
VB.NET
Imports System
Module Program
Sub Main()
Dim ts = "1711022400000"
Dim n = Long.Parse(ts)
Dim ms = If(ts.Length >= 13, n, n * 1000)
Dim iso = DateTimeOffset.FromUnixTimeMilliseconds(ms).ToUniversalTime().ToString("o")
Console.WriteLine(iso)
End Sub
End Module
Normalize to ms and use DateTimeOffset to convert to UTC and output ISO.
- Std.
Related tools
Use the tool when you need to generate or validate output fast.
Trust and privacy
Copy/paste-friendly by design. Still, treat real production secrets carefully.
- Prefer synthetic examples when sharing screens or recording.
- Do not paste real API keys, tokens, or personal data unless you fully trust your environment.
- If you need ordering, do not use UUID v4 as a sortable id: add createdAt or use sortable ids.