Millisecondi vs secondi: la confusione di unità che rompe ogni app

Il bug di timestamp più comune è passare millisecondi dove ci si aspettano secondi, o viceversa. Impara la regola delle 10 vs 13 cifre, i default dei linguaggi, le implicazioni per i database e i pattern di conversione sicuri.

Perché esistono due standard

Il tempo Unix è stato originariamente definito in secondi: un intero sembrava naturale per un sistema che si incrementava a ogni tic di clock. L'oggetto Date di JavaScript, introdotto nel 1995, scelse i millisecondi per gestire la temporizzazione di eventi sotto il secondo nel browser. Molti database e linguaggi backend mantennero i secondi Unix come default. Oggi entrambi gli standard coesistono in ogni codice che attraversa il confine JavaScript-server, ed è per questo che un valore può sembrare valido e rappresentare comunque una data a decine di migliaia di anni.

Quale unità usa ogni linguaggio

Il modo più sicuro per ricordare la divisione: le API Date del browser di solito vogliono millisecondi, le API server in stile Unix di solito espongono secondi, e le librerie di tempo più recenti spesso offrono entrambi. Non dedurre l'unità dal solo linguaggio leggendo la documentazione di un'API di terze parti; controlla la descrizione del campo e gli esempi.

  • Milliseconds: JavaScript Date.now(), Java System.currentTimeMillis(), Java Instant.toEpochMilli(), .NET ToUnixTimeMilliseconds()
  • Seconds: Python time.time() (float), PHP time(), Go time.Now().Unix(), Ruby Time.now.to_i, C time(NULL), PostgreSQL EXTRACT(EPOCH)
  • Both: Rust — duration.as_secs() for seconds, duration.as_millis() for milliseconds
  • Python note: time.time() returns a float, so milliseconds are available as int(time.time() * 1000)

Riconoscere l'unità dal valore

Un'euristica affidabile per le date moderne: un numero a 10 cifre è in secondi; a 13 cifre è in millisecondi. I secondi Unix attuali sono intorno a 1,7–2,1 miliardi (10 cifre) e non raggiungeranno 13 cifre fino all'anno 33658. I millisecondi Unix attuali hanno già 13 cifre. L'euristica è più forte dagli anni 2000 fino a qualche migliaio di anni avanti; per date storiche, negative o fixture di test compatte, usa unità esplicite invece di indovinare.

  • valore a 10 cifre → secondi (es. 1700000000 = 2023-11-14 UTC)
  • valore a 13 cifre → millisecondi (es. 1700000000000 = 2023-11-14 UTC)
  • valore a 16 cifre → microsecondi (dividi per 1,000,000 per i secondi)
  • valore negativo → data prima del 1° gennaio 1970 (secondi o millisecondi)

Pattern di conversione sicuri

La conversione in sé è semplice aritmetica; la parte difficile è scegliere dove farla. Converti al confine del sistema, dai un nome al valore convertito ed evita di passare numeri grezzi ambigui attraverso più livelli.

  • Seconds to milliseconds: seconds * 1000
  • Milliseconds to whole seconds — JavaScript: Math.floor(ms / 1000)
  • Milliseconds to whole seconds — Python: ms // 1000
  • Milliseconds to whole seconds — Go: ms / 1000 (integer division)
  • Universal guard in JavaScript: const toMs = ts => ts < 1e11 ? ts * 1000 : ts

Come compaiono i bug di unità in produzione

Un bug secondi-vs-millisecondi spesso sopravvive alla validazione perché entrambi i valori sono solo numeri. Compare di solito più tardi come una data impossibile: gennaio 1970 in JavaScript quando i secondi sono stati trattati come millisecondi, o un anno molto lontano quando un backend ha trattato i millisecondi come secondi.

  • Data del 1970 nella UI JavaScript → secondi passati a new Date() senza moltiplicare per 1000
  • Anno 50000+ in Python, Go o PHP → millisecondi passati a un'API che si aspettava secondi
  • Token scaduti che non scadono mai → timestamp di scadenza salvato nell'unità sbagliata
  • Voci di cache che spariscono subito → millisecondi divisi due volte o secondi moltiplicati due volte
  • Grafici di analytics con intervalli vuoti → i limiti della query usano un'unità diversa dai timestamp degli eventi salvati

Convenzioni di denominazione per API e database

Una piccola convenzione di denominazione evita la maggior parte di questi bug. Non pubblicare mai un campo API chiamato timestamp a meno che la documentazione non sia eccezionalmente chiara. Preferisci nomi di campo che includano significato e unità.

  • createdAtMs — Unix milliseconds, best for JavaScript clients
  • createdAtSeconds — Unix seconds, common for backend services
  • createdAtIso — ISO 8601 string, useful for human-readable API responses
  • expiresAtUnixSeconds — explicit enough for auth tokens and signed URLs
  • event_time TIMESTAMPTZ — native database time, with conversion handled by the database

FAQ millisecondi vs secondi

Un timestamp a 13 cifre è sempre in millisecondi?
Per i timestamp Unix reali moderni, sì: 13 cifre di solito significano millisecondi. Timestamp in secondi molto lontani nel futuro possono anch'essi raggiungere 13 cifre, quindi i sistemi critici dovrebbero portare metadati di unità espliciti.
Devo memorizzare secondi o millisecondi?
Memorizza l'unità che il tuo sistema usa naturalmente, ma documentala e mantienila coerente. I sistemi molto orientati a JavaScript usano spesso millisecondi; i backend in stile Unix e molti database usano spesso secondi o colonne datetime native.
Perché usare Math.floor(ms / 1000) invece di ms / 1000?
I secondi Unix sono di solito secondi interi. Math.floor rimuove la parte frazionaria così le API che si aspettano secondi interi non ricevono un decimale.
Come converto i millisecondi in secondi?
Dividi per 1000 e scarta la frazione: Math.floor(ms / 1000) in JavaScript, ms // 1000 in Python, o ms / 1000 con divisione intera in Go. Per l'inverso, moltiplica i secondi per 1000.