Cos'è un Timestamp Unix (e Come si Legge)
Un timestamp Unix è un numero intero che rappresenta un istante preciso nel tempo: il totale di secondi trascorsi dal 1° gennaio 1970 alle 00:00:00 UTC, il cosiddetto “epoch” Unix. Il valore 1700000000, per esempio, corrisponde al 14 novembre 2023 alle 22:13:20 UTC. Non ha fuso orario proprio ed è per questo che database, API e log lo usano come formato standard per registrare quando qualcosa è successo.
Cos’è realmente un timestamp Unix
Un timestamp Unix conta i secondi (a volte i millisecondi) passati dal 1° gennaio 1970, 00:00:00 UTC. Quel momento è la data zero da cui parte il conteggio; ogni secondo successivo aumenta il valore di uno, ogni secondo precedente lo rende negativo. È un sistema semplice, ma proprio per questo estremamente efficace.
I computer preferiscono questa rappresentazione a una stringa formattata come “14/11/2023 22:13:20” per tre motivi concreti. Primo, è compatta: un intero occupa meno spazio di una stringa e si confronta in una singola operazione numerica invece di un parsing testuale. Secondo, è priva di ambiguità: non serve sapere se “14/11/2023” significa 14 novembre o 11 aprile a seconda del paese, il numero è lo stesso ovunque nel mondo. Terzo, è facile da ordinare e su cui fare calcoli: sottrarre due timestamp dà direttamente la differenza in secondi, senza dover analizzare mesi, giorni e fusi orari a mano. Se hai mai scritto una query SQL con WHERE created_at > 1700000000, hai già sfruttato esattamente questo vantaggio.
Esempio pratico: leggere valori di timestamp reali
Ecco alcuni valori di riferimento, utili per farsi un’idea della scala dei numeri in gioco:
| Timestamp Unix (secondi) | Data e ora UTC |
|---|---|
| 0 | 1° gennaio 1970, ore 00:00:00 UTC (l’epoch stesso) |
| 1000000000 | 9 settembre 2001, ore 01:46:40 UTC |
| 1700000000 | 14 novembre 2023, ore 22:13:20 UTC |
| 2000000000 | 18 maggio 2033, ore 03:33:20 UTC |
| 2147483647 | 19 gennaio 2038, ore 03:14:07 UTC |
Prendiamo il terzo valore, 1700000000, e vediamo perché atterra a novembre 2023. Un miliardo di secondi equivale a poco più di 31 anni e mezzo; da 0 (1970) a 1000000000 (2001) passa esattamente quell’intervallo. Da lì a 1700000000 ci sono altri 700 milioni di secondi, cioè poco più di 22 anni, che portano dal settembre 2001 al novembre 2023. Non serve fare i conti a mente ogni volta: è la logica con cui il numero cresce, ed è utile per capire a colpo d’occhio se un timestamp che stai leggendo in un log è “recente” o è vecchio di anni solo guardando quante cifre ha e quanto è distante da un valore che già conosci.
Secondi o millisecondi? Come distinguerli
Uno degli errori più frequenti quando si lavora con i timestamp è confondere secondi e millisecondi. Un timestamp in secondi, oggi, ha 10 cifre: 1700000000. Lo stesso istante espresso in millisecondi ha 13 cifre: 1700000000000, sempre il 14 novembre 2023, semplicemente moltiplicato per 1000.
La confusione nasce perché non tutti i sistemi usano la stessa unità. Date.now() in JavaScript e molte API web restituiscono millisecondi, mentre le chiamate di sistema Unix, cron e la maggior parte degli strumenti a riga di comando in ambiente Unix/Linux lavorano in secondi. Incollare un valore in millisecondi in un campo che si aspetta secondi (o viceversa) produce un errore di un fattore 1000: se passi 1700000000000 a un tool che interpreta i secondi, il risultato non sarà novembre 2023, ma una data proiettata migliaia di anni nel futuro, ben oltre qualsiasi cosa abbia senso. Il modo più rapido per accorgersi dell’errore è proprio contare le cifre: 10 vuol dire secondi, 13 vuol dire millisecondi.
Convertire un timestamp in una data
Hai un valore come created_at in una riga di database, o in un campo di risposta di un’API, e non riesci a capire subito a quale data corrisponda? Incollalo qui sotto per vederlo tradotto all’istante.
Convertire una data in un timestamp
Il percorso inverso serve altrettanto spesso: devi programmare qualcosa per una data e un’ora precise, per esempio impostare la scadenza di un token, il campo exp di un JWT, o pianificare un job cron che deve partire in un momento esatto, e la tua API o il tuo sistema si aspettano il valore come timestamp Unix, non come stringa leggibile.
Errori comuni e casi particolari
Confondere secondi e millisecondi. È l’errore più comune in assoluto, discusso nel dettaglio più sopra: conta sempre le cifre prima di incollare un valore in un campo che si aspetta l’altra unità.
Il problema dell’anno 2038. I sistemi che memorizzano il timestamp come intero con segno a 32 bit hanno un limite massimo di 2147483647, corrispondente esattamente al 19 gennaio 2038 alle 03:14:07 UTC. Superato quel valore, il numero va in overflow e “torna indietro” a un valore negativo, mandando in tilt qualsiasi logica basata sul confronto di date. È lo stesso tipo di bug del millennium bug, ma legato al modo in cui il tempo viene rappresentato in binario. I sistemi moderni a 64 bit non hanno questo limite: possono rappresentare date migliaia di anni nel futuro senza problemi.
Fusi orari: la confusione non è nel timestamp, ma nella visualizzazione. Il timestamp Unix in sé non ha alcun fuso orario, rappresenta un istante assoluto e identico per chiunque, ovunque nel mondo. La confusione nasce quando quel numero viene mostrato come data leggibile: due persone in due fusi orari diversi che guardano lo stesso timestamp 1700000000 vedranno due orari sull’orologio differenti (uno alle 22:13 UTC, l’altro magari alle 19:13 se è tre ore indietro), ma stanno guardando esattamente lo stesso istante. Il bug non è nel dato, è in come lo si formatta.
Timestamp negativi. Un valore negativo rappresenta una data precedente al 1° gennaio 1970. Per esempio, -86400 (un giorno espresso in secondi, con il segno meno) corrisponde al 31 dicembre 1969. Non tutti gli strumenti e i sistemi supportano valori negativi: alcune librerie e alcuni campi di database li rifiutano o li troncano a zero, quindi è bene verificarlo prima di affidarsi a un timestamp negativo in produzione.
Domande frequenti
Cos’è un timestamp Unix? È il numero totale di secondi (o millisecondi) trascorsi dall’epoch Unix, ovvero il 1° gennaio 1970 alle 00:00:00 UTC. Viene usato universalmente in programmazione per rappresentare un istante preciso senza ambiguità di fuso orario.
Come faccio a capire se il mio timestamp è in secondi o millisecondi? Conta le cifre. Un timestamp in secondi oggi ha 10 cifre (per esempio 1700000000); lo stesso istante in millisecondi ne ha 13 (1700000000000). Se il numero ha 13 cifre e provi a interpretarlo come secondi, otterrai una data assurdamente lontana nel futuro: è il segnale che hai sbagliato unità.
Cos’è il problema dell’anno 2038? È il limite dei sistemi che salvano il timestamp come intero con segno a 32 bit: il valore massimo rappresentabile è 2147483647, corrispondente al 19 gennaio 2038 alle 03:14:07 UTC. Oltre quella soglia il numero va in overflow e diventa negativo, causando errori di calcolo sulle date. I sistemi a 64 bit non hanno questo limite.
Posso convertire una data precedente al 1970? Sì, con un timestamp negativo. Per esempio -86400 corrisponde al 31 dicembre 1969. Tieni presente che non tutti gli strumenti o i database gestiscono correttamente i valori negativi, quindi conviene testarlo nel sistema specifico che stai usando.
Perché i database salvano le date come timestamp Unix invece che come stringhe di testo?
Perché un intero è più compatto, non ambiguo tra formati regionali diversi (giorno/mese contro mese/giorno) e permette di ordinare, confrontare e sottrarre le date con semplici operazioni numeriche, invece di dover fare il parsing di una stringa ogni volta. Una colonna created_at in formato timestamp si confronta e si indicizza molto più velocemente di una colonna testuale con la data scritta per esteso.