Ogni sistema che memorizza un istante pone prima o poi la stessa domanda: questo numero è in secondi o in millisecondi? I timestamp Unix sembrano banali — un intero che conta i secondi trascorsi dal 1 gennaio 1970 — e proprio per questo vengono gestiti male. Un valore sbagliato di un fattore 1000, una data nel 1970, uno sfasamento di fuso che compare solo negli utenti dall’altra parte del mondo: tutto nasce dai soliti pochi malintesi.
Questo articolo spiega cosa misura davvero un timestamp Unix, come distinguere secondi e millisecondi, come si inserisce ISO 8601 e come convertire tra formati senza indovinare.
Cosa è davvero un timestamp Unix
Un timestamp Unix — chiamato anche epoca — è il numero di secondi trascorsi dalle 00:00:00 UTC del 1 gennaio 1970, l’epoca Unix. È un intero senza informazioni di fuso orario: lo stesso numero descrive lo stesso istante in tutto il mondo.
Non portando con sé un fuso, l’epoca è un formato di scambio naturale per le macchine. API, log, database e code di messaggi memorizzano timestamp; gli esseri umani leggono date. La conversione tra i due mondi è dove vivono gli errori.
Nota cosa un timestamp non contiene: fuso orario, locale o calendario. 1758537600 è un istante. Che a Bangkok siano le 21:00 e a Madrid le 14:00 dipende solo da come lo presentate.
Secondi contro millisecondi: l’errore più frequente
Due convenzioni convivono e si trovano ovunque:
- Secondi — oggi 10 cifre, per esempio
1758537600. Il Unix storico,Unix()di Go,getEpochSecond()di Java, Redis e la maggior parte dei database usano quest’unità. - Millisecondi — 13 cifre, per esempio
1758537600000.Date.now()di JavaScript,getTime()di Java e la maggior parte delle API dei browser usano quest’unità.
Confondere le unità fa saltare la data al 1970 o al 2286. Non esiste una regola universale per riconoscerle, quindi la strada affidabile è conoscere il contratto della fonte. Se dovete indovinare, 10 cifre sono quasi sempre secondi e 13 quasi sempre millisecondi — ma indovinare è l’errore, non la soluzione.
Regola: memorizzate l’unità accanto al valore. Usate un nome di colonna (created_at_ms), un campo API esplicito o una proprietà unit. Qualsiasi cosa è meglio di un intero nudo chiamato time.
ISO 8601: il lato leggibile
Le stringhe ISO 8601 sono il volto opposto dei numeri d’epoca: leggibili, ordinabili in UTC e non ambigue quando riportano uno sfasamento.
2026-09-22T14:00:00Z # UTC, indicato dalla Z finale
2026-09-22T14:00:00+02:00 # lo stesso istante, ora locale di Berlino
2026-09-22T14:00:00.123Z # conserva i millisecondi
La Z finale e lo sfasamento numerico non sono decorazioni. Senza uno dei due la stringa non ha fuso e il codice deve indovinare — ed è così che «la stessa ora» diventa silenziosamente un errore di tre ore.
Fusi orari e UTC
Memorizzate e confrontate in UTC, e convertite in un fuso locale nel layer di presentazione, solo quando dovete mostrare qualcosa a una persona.
const now = Date.now(); // millisecondi dall’epoca
const seconds = Math.floor(now / 1000); // secondi dall’epoca
new Date(seconds * 1000).toISOString(); // "2026-09-22T14:00:00.000Z"
Due regole evitano la maggior parte dei problemi di fuso:
- Mai confrontare un’ora locale naiva con un’altra. Serializzate prima entrambe in istanti, poi confrontate.
- Conservate lo sfasamento accanto al valore quando conta il fuso dell’utente (appuntamenti, orari, periodi di fatturazione). Un istante UTC più un identificante IANA come
Europe/Romeè meglio di uno sfasamento fisso, perché gli sfasamenti fissi cambiano con l’ora legale.
Cheat sheet di conversione
| Convertire | JavaScript | Python |
|---|---|---|
| Millisecondi in stringa data | new Date(1758537600000).toISOString() |
datetime.fromtimestamp(1758537600, tz=timezone.utc) |
| Stringa data in secondi | Math.floor(Date.parse(s) / 1000) |
int(dt.replace(tzinfo=timezone.utc).timestamp()) |
| Secondi in millisecondi | seconds * 1000 |
seconds * 1000 |
| Ora corrente | Date.now() (millisecondi) |
int(time.time()) (secondi) |
Nota che Date.now() restituisce millisecondi mentre time.time() restituisce secondi: l’illustrazione compatta del fatto che l’unità è una convenzione per linguaggio, non uno standard universale.
Errori da evitare
- Moltiplicare per 1000 «per sicurezza». Decidete in base al contratto, mai in base al numero di cifre.
- Memorizzare un’ora locale senza sfasamento. L’ora legale romperà l’aritmetica prima o poi.
- Parsare spezzettando le stringhe. Usate il parser della libreria standard: ISO 8601 porta con sé settimana, formato compatto e frazionari che fanno fallire il codice scritto a mano.
- Formati di data dentro SQL. Tenete il valore numerico o in UTC nel database e formattate nell’applicazione, dove controllate locale e fuso.
- Usare il timestamp completo come riferimento umano. Chi lo legge ad alta voce perde cifre. Riducete o hashate se serve un riferimento corto.
Provalo
Incollate un valore d’epoca o una stringa data in un convertitore di timestamp per passare tra secondi, millisecondi, ISO 8601 e la vostra ora locale. La conversione avviene nel browser, così nessun timestamp — sensibile o no — deve lasciare il vostro dispositivo per essere leggibile.