Skip to content

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).

← Developer Zone
Updated: 2026-03-22

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.

Use this after capturing the real payload

Work from the request or response body that actually failed instead of rebuilding JSON from memory.

Pick the language that matches the incident

The useful path here is fast adaptation: choose your stack, then copy only after reading the notes around parsing and formatting.

Validate the result with the tool

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.

Languages

13

Related tools

3

Topics

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.

Bash
Check notes

Review the notes for setup details.

C#
Built-in

Built-in or runtime API

Delphi
Check notes

Review the notes for setup details.

Go
Built-in

Built-in or runtime API

Java
Check notes

Review the notes for setup details.

JavaScript
Built-in

Built-in or runtime API

Kotlin
Check notes

Review the notes for setup details.

PHP
Built-in

Built-in or runtime API

Python
Built-in

Built-in or runtime API

Ruby
Built-in

Built-in or runtime API

Rust
External

chrono = "0.4".

TypeScript
Built-in

Built-in or runtime API

VB.NET
Built-in

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.

1. Start with the problem

Make sure the article really matches the issue you are debugging before copying code just because the title looks close.

2. Read the notes

That is where portability limits, dependency requirements, and runtime assumptions usually appear.

3. Validate the output

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

bash
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
Explanation

Detects ms vs s by length, normalizes to seconds, and uses date in UTC to print ISO. Useful for quick debugging.

Notes
  • Works with GNU date and BSD date (macOS).
  • If your timestamp is a string with spaces, trim it first.

C#

csharp
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);
Explanation

Normalize to milliseconds and use DateTimeOffset.FromUnixTimeMilliseconds to get a UTC ISO string (o format).

Notes
  • Std.
  • If input can be invalid, catch FormatException/OverflowException.

Delphi

delphi
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.
Explanation

Converts to seconds when the input is milliseconds and uses UnixToDateTime(..., True) as UTC. DateToISO8601 returns an ISO string.

Notes
  • Std: System.DateUtils.
  • To show local time, convert to local timezone before formatting.

Go

go
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))
}
Explanation

Normalize to milliseconds and build a time.Time using nanoseconds. Then print RFC3339 in UTC.

Notes
  • Std.
  • If parsing from string, handle errors in production.

Java

java
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());
  }
}
Explanation

Instant.ofEpochMilli is the modern java.time approach. It prints ISO-8601 in UTC.

Notes
  • Std (Java 8+).

JavaScript

javascript
JavaScript
const ts = "1711022400000";
const n = Number(ts);
const ms = ts.length >= 13 ? n : n * 1000;
console.log(new Date(ms).toISOString());
Explanation

JS Date works in milliseconds. Normalize to ms and use toISOString() for UTC.

Notes
  • Std.
  • If numbers get huge, watch precision (Number is float).

Kotlin

kotlin
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())
}
Explanation

In Kotlin/JVM you can use Instant (java.time) just like in Java.

Notes
  • Std (JVM).

PHP

php
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;
Explanation

Normalize to ms, convert to seconds for DateTimeImmutable epoch constructor, and force UTC with DateTimeZone.

Notes
  • Std.
  • If your timestamp comes as float/decimals, normalize first.

Python

python
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())
Explanation

Convert to seconds (float) and create a UTC datetime. isoformat() outputs ISO for logs.

Notes
  • Std.
  • In production, store UTC and convert at the UI if needed.

Ruby

ruby
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)
Explanation

Normalize to seconds and use Time.at(...).utc.iso8601 to get a UTC timestamp.

Notes
  • Std.
  • This example preserves milliseconds when they are present in the input.

Rust

rust
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());
}
Explanation

With chrono, convert to seconds and create a DateTime<Utc>. to_rfc3339 outputs an ISO string with timezone.

Notes
  • Dependency: chrono = "0.4".

TypeScript

ts
TypeScript
const ts = "1711022400000";
const n = Number(ts);
const ms = ts.length >= 13 ? n : n * 1000;
console.log(new Date(ms).toISOString());
Explanation

In TS/JS the trick is the same: Date uses ms. Use toISOString() for UTC.

Notes
  • Std.
  • For precision and safety, avoid Number in backends when handling huge ints.

VB.NET

vbnet
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
Explanation

Normalize to ms and use DateTimeOffset to convert to UTC and output ISO.

Notes
  • 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.