Perché Unix memorizza i timestamp in un numero intero con segno?


24

Perché viene utilizzato un numero intero con segno per rappresentare i timestamp? C'è un inizio chiaramente definito a 1970 che è rappresentato come 0, quindi perché dovremmo aver bisogno di numeri prima? I timestamp negativi vengono utilizzati ovunque?


2
Ecco perché Nostradamus non ha potuto usare il suo computer per scrivere le sue previsioni per gli anni 3000+ ... avrebbe causato un overflow e avrebbe mostrato le sue date come negative. Penso che lo abbiano chiamato il bug Y3K o qualcosa del genere!
Jeach

3
Gli antichi romani avevano un problema ancora peggiore quando i numeri degli anni passavano da negativi a positivi. Lo avrebbero chiamato il problema Y0K se avessero avuto il modo di esprimere il numero zero. Cool}
Keith Thompson il

Risposte:


35

Le prime versioni di C non avevano numeri interi senza segno. (Alcuni programmatori utilizzavano i puntatori quando avevano bisogno di aritmetica senza segno.) Non so quale sia venuto prima, la time()funzione o i tipi senza segno, ma sospetto che la rappresentazione sia stata stabilita prima che i tipi senza segno fossero universalmente disponibili. E il 2038 fu abbastanza lontano in futuro che probabilmente non valeva la pena preoccuparsi. Dubito che molte persone pensassero che Unix sarebbe ancora esistito da allora.

Un altro vantaggio di un firmato time_tè che estenderlo a 64 bit (che sta già accadendo su alcuni sistemi) consente di rappresentare volte diverse centinaia di miliardi di anni nel futuro senza perdere la capacità di rappresentare i tempi prima del 1970. (Ecco perché mi oppongo al passaggio a un 32 bit senza segno time_t ; abbiamo abbastanza tempo per passare a 64 bit.)


7
La timefunzione è più antica dell'epoca: Unix v1 (nel 1971) contava in unità di 1/60 di secondo, da mezzanotte del 1971/01/01. Era già noto un bug che "L'utente con una mentalità cronologica noterà che 2 ** 32 sessantesimo di secondo è solo circa 2,5 anni".unsigned Fu introdotto da K&R nel 1978 , ben dopo che fu stabilita l'epoca del 1970.
Gilles 'SO- smetti di essere malvagio' il

Ho fatto un test rapido e sul mio box Linux a 64 bit. gmtimee localtimemassimo nell'anno 2147483647 (con il secondo successivo dopo aver dato -2147483648 come l'anno). Quindi, per superare i 55 bit di tempo, qualcuno dovrà aggiornare la routine di output per utilizzare un int a 64 bit per l'anno invece di un int a 32 bit senza segno. Spero che qualcuno si occuperà di quel bug nei prossimi due miliardi di anni.
Freiheit,

@freiheit: interessante. Il problema è che il struct tmtipo ha un membro tm_year(che rappresenta gli anni dal 1900) che è di tipo int. I sistemi a 64 bit possono facilmente avere un 64-bit time_t, ma in genere hanno un 32-bit int. (Se charè 8 bit e int64 bit, allora shortpuò essere 16 o 32 bit e non ci sarà un tipo predefinito per le altre dimensioni.) Ma time()è probabilmente l'unica funzione <time.h>che richiede davvero supporto a livello di sistema; puoi scrivere il tuo codice per convertire i time_tvalori in stringhe leggibili dall'uomo.
Keith Thompson,

12

Supporta data e ora prima del 1 ° gennaio 1970.


1
Questo fa solo 68 anni nel passato - 1902. Questo sembra abbastanza poco.
Bakudan,

2
POSIX non richiede time_tsolo 32 bit; è già a 64 bit su molti sistemi.
Keith Thompson,

1
mktime()la funzione ritorna -1in caso di errore, quindi è probabilmente impossibile distinguere tra i timestamp corretti prima del 1970-01-01 e l'errore ts. Le date di apparenza prima del 01-01-1901 sono vietate
DimG

@DimG: è difficile distinguere tra un errore e il timestamp specifico 1969-12-31 23:59:59 UTC. Un valore negativo diverso da quello -1non è ambiguo.
Keith Thompson,

1
@mtraceur: lo standard C non richiede l' mktime()impostazione di una chiamata non riuscita errno. (POSIX sì.)
Keith Thompson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.