Nessun upload, 100% locale, nessun account

Articolo

Timestamp Unix ed espressioni cron spiegate

Un timestamp Unix è semplicemente un intero. Un'espressione cron è semplicemente cinque campi. Entrambi compaiono continuamente nel lavoro backend, ed entrambi creano problemi in modo prevedibile: uno a causa dei fusi orari, l'altro a causa dell'unità.

Cos'è un timestamp Unix

Un timestamp Unix conta il numero di secondi trascorsi dal 1970-01-01 00:00:00 UTC, un punto di riferimento noto come epoca Unix. Questa definizione ha due conseguenze importanti. Prima, il conteggio è in UTC: non è incorporato alcun fuso orario nel numero stesso. 1718400000 indica lo stesso istante ovunque nel mondo indipendentemente da dove si trova la macchina che lo memorizza. Seconda, l'epoca è definita in secondi, non in altre unità. Un valore come 1718400000 è sempre secondi dalla mezzanotte del 1 gennaio 1970 UTC, a meno che un sistema o protocollo non abbia fatto una scelta diversa in modo esplicito. I timestamp sono privi di fuso orario per progetto, il che è precisamente il motivo per cui sono utili per la registrazione, i database e la comunicazione tra sistemi dove gli orologi in regioni diverse devono riferirsi allo stesso momento senza ambiguità.

Timeline che mostra l'epoca Unix al 1970-01-01 00:00:00 UTC sulla sinistra, un timestamp corrente al centro e il limite di overflow del 2038 sulla destra, contrassegnato con il massimo di un intero con segno a 32-bit.

Secondi, millisecondi e il problema del 2038

Molti runtime e API moderni usano millisecondi invece di secondi. Il metodo Date.now() di JavaScript restituisce millisecondi, quindi 1718400000000 è lo stesso istante del valore a precisione di secondo 1718400000. Quando si riceve un timestamp non familiare, la grandezza indica l'unità: un numero a 10 cifre è quasi sempre in secondi; uno a 13 cifre è quasi sempre in millisecondi. Il problema del 2038 deriva da una scelta diversa: memorizzare un timestamp a precisione di secondo in un intero con segno a 32-bit. Il valore massimo di un intero con segno a 32-bit è 2147483647, che corrisponde al 2038-01-19 03:14:07 UTC. Dopo quel secondo, il contatore va in overflow a un grande numero negativo e la data torna al 1901 sui sistemi che non gestiscono il limite. La soluzione è usare la memorizzazione a 64 bit. La maggior parte dei sistemi operativi e database attuali lo fa già, ma i sistemi embedded, i dispositivi di rete e i formati di file vecchi che hanno fissato la larghezza del campo decenni fa rimangono a rischio.

Conversione da epoch a data leggibile: il passaggio del fuso orario

Convertire un valore epoch in una data leggibile richiede due passaggi: recuperare i componenti della data UTC dall'intero, poi applicare un offset UTC per ottenere l'orario locale. Il timestamp stesso è in UTC. Quando si chiede quale data rappresenta 1718325000, la risposta corretta è 2024-06-14 alle 00:30 in UTC. A New York (UTC-4 in estate), quello stesso secondo cade il 2024-06-13 alle 20:30 della sera precedente: cambia la data, non solo l'ora. Questo è il passaggio che produce risultati errati quando viene saltato: uno sviluppatore registra il timestamp grezzo in UTC, uno strumento di reporting lo rende nell'orario locale senza conversione, e la data appare sfasata di ore o di un giorno intero. Lo strumento timestamp-converter di Sunasty gestisce questo in modo esplicito: si inserisce un valore epoch e lo strumento mostra la data e l'orario UTC accanto alla data e all'orario locali del proprio dispositivo, così un cambio di giorno come questo è visibile a colpo d'occhio. La conversione viene eseguita interamente nel browser e nulla di ciò che si incolla viene inviato da nessuna parte.

Due griglie di calendario affiancate per lo stesso valore epoch: la griglia UTC evidenzia un giorno del calendario e la griglia di New York (UTC-4) evidenzia il giorno precedente, mostrando la data locale che retrocede a causa del fuso orario.

Sintassi cron: cinque campi, intervalli, passi ed elenchi

Un'espressione cron pianifica lavori ricorrenti sui sistemi di tipo Unix. La sintassi standard ha cinque campi separati da spazi: minuto (0-59), ora (0-23), giorno del mese (1-31), mese (1-12), giorno della settimana (0-7, dove sia 0 che 7 rappresentano la domenica). Un asterisco (*) in un campo significa "ogni valore valido". L'espressione 30 8 * * 1-5 viene eseguita alle 08:30 dal lunedì al venerdì. Gli intervalli usano un trattino: 1-5 copre i valori 1, 2, 3, 4, 5. Gli elenchi usano le virgole: 1,15 significa il 1° e il 15°. I passi usano una barra: */15 nel campo minuto significa ogni 15 minuti (0, 15, 30, 45). Questi combinatori possono comparire insieme: 0-30/10 significa 0, 10, 20, 30. Una cosa che cron non ha è un campo per il fuso orario. Il daemon legge l'orologio della macchina su cui gira, impostato sul fuso orario locale del server. Se il server è su UTC ma uno sviluppatore si aspetta l'orario locale, il lavoro viene eseguito all'ora di orologio sbagliata. La regola pratica è trattare le pianificazioni cron come espressioni dell'orario locale del server e documentare il fuso orario del server accanto alla riga cron.

Usare il timestamp-converter in locale

Il timestamp-converter di Sunasty converte in entrambe le direzioni: da epoch a data leggibile e da data leggibile a epoch. Si può inserire un valore a precisione di secondo o a precisione di millisecondo; lo strumento rileva l'unità dalla grandezza. Mostra il risultato in UTC e nel fuso orario locale del proprio dispositivo, fianco a fianco, insieme ai valori grezzi in secondi e millisecondi pronti da copiare. Un pulsante Now compila il timestamp corrente con un clic, un modo rapido per sapere qual è il tempo Unix attuale senza aprire un terminale. Non c'è un selettore di fuso orario separato: la colonna locale riflette sempre qualunque fuso orario sia impostato al momento nel browser. Tutto questo funziona nel browser. Il valore incollato nel campo viene letto da JavaScript lato client e non lascia mai il dispositivo.

Strumenti citati in questo articolo

Domande frequenti

Perché JavaScript usa i millisecondi invece dei secondi?

L'oggetto Date di JavaScript è stato progettato per lavorare con una precisione inferiore al secondo fin dall'inizio, e i millisecondi forniscono mille volte la risoluzione dei secondi senza richiedere un punto decimale. Il compromesso è che i valori sono più grandi, il che spiega perché Date.now() produce un numero a 13 cifre mentre la maggior parte dei timestamp lato server ha 10 cifre.

Ogni server che esegue cron deve essere su UTC?

No, ma far girare i server su UTC è una pratica comune precisamente perché rimuove l'ambiguità. Quando un server è su UTC, un'espressione cron come 0 2 * * * significa 02:00 UTC e quell'orario è stabile durante tutto l'anno. Su un server in un fuso che osserva l'ora legale, lo stesso lavoro viene eseguito a un istante UTC diverso in estate e in inverno, e potrebbe essere eseguito due volte o saltare una volta al cambio dell'orario.

Qual è il tipo di memorizzazione sicuro per i timestamp oltre il 2038?

Un intero con segno a 64 bit conserva i timestamp a precisione di secondo fino all'anno 292277026596, ben oltre qualsiasi preoccupazione pratica. La maggior parte dei database attuali memorizza i timestamp come valori a 64 bit per impostazione predefinita. Se si lavora con uno schema legacy o un formato di file binario che usa campi a 32-bit, migrare alla memorizzazione a 64 bit prima del limite del 2038 è la soluzione corretta.