Dlaczego Unix przechowuje znaczniki czasu w podpisanej liczbie całkowitej?


24

Dlaczego podpisana liczba całkowita jest używana do reprezentowania znaczników czasu? Jest jasno określony początek w 1970 roku, który jest reprezentowany jako 0, więc po co mielibyśmy wcześniej liczby? Czy gdziekolwiek są stosowane ujemne znaczniki czasu?


2
Dlatego Nostradamus nie mógł użyć swojego komputera do napisania swoich prognoz na lata 3000+ ... spowodowałoby to przepełnienie i pokazałoby jego daty jako negatywne. Myślę, że nazwali to błędem Y3K czy coś takiego!
Jeach,

3
Starożytni Rzymianie mieli jeszcze gorszy problem, gdy rok zmienił się z ujemnego na dodatni. Nazwaliby to problemem Y0K, gdyby mieli sposób na wyrażenie liczby zero. 8-)}
Keith Thompson

Odpowiedzi:


35

Wczesne wersje C nie miały liczb całkowitych bez znaku. (Niektórzy programiści używali wskaźników, gdy potrzebowali arytmetyki bez znaku). Nie wiem, która była pierwsza, time()funkcja lub typy bez znaku, ale podejrzewam, że reprezentacja została ustanowiona, zanim typy bez znaku były powszechnie dostępne. A rok 2038 był na tyle daleko w przyszłości, że prawdopodobnie nie warto było się o to martwić. Wątpię, aby wiele osób uważało, że do tego czasu Unix będzie istniał.

Kolejną zaletą podpisu time_tjest to, że rozszerzenie go do 64 bitów (co już dzieje się w niektórych systemach) pozwala reprezentować czasy kilkaset miliardów lat w przyszłość bez utraty zdolności do reprezentowania czasów sprzed 1970 roku. (Dlatego sprzeciwiam się przejściu na 32-bit bez znaku time_t ; mamy wystarczająco dużo czasu na przejście do 64 bitów.)


7
timeFunkcja jest starszy niż epoki: Unix v1 (1971) liczone w jednostkach 1 / 60. sekundy, od północy na 1971/01/01. Znany już błąd polegał na tym, że „chronologicznie myślący użytkownik zauważy, że 2 ** 32 sześćdziesiątych sekundy to tylko około 2,5 roku”.unsigned Został wprowadzony przez K&R w 1978 roku , długo po ustanowieniu epoki z 1970 roku.
Gilles „SO- przestań być zły”

Zrobiłem szybki test na moim 64-bitowym pudełku z linuksem. gmtimei localtimemaks. w roku 2147483647 (z następną sekundą po podaniu -2147483648 jako roku). Aby minąć 55 bitów czasu, ktoś będzie musiał zaktualizować procedurę wyjściową, aby użyć 64-bitowej liczby int dla roku zamiast 32-bitowej liczby bez znaku. Mam nadzieję, że ktoś rozwiąże ten problem w ciągu najbliższych kilku miliardów lat.
freiheit,

@freiheit: Interesujące. Problem polega na tym, że struct tmtyp ma element członkowski tm_year(reprezentujący lata od 1900 r.), Który jest typu int. Systemy 64-bitowe mogą łatwo mieć wersję 64-bitową time_t, ale zazwyczaj mają wersję 32-bitową int. (Jeśli charma 8 bitów i int64 bitów, shortmoże mieć 16 lub 32 bity i nie będzie predefiniowanego typu dla drugiego rozmiaru.) Ale time()prawdopodobnie jest to jedyna funkcja, <time.h>która naprawdę wymaga wsparcia na poziomie systemu; możesz napisać własny kod do konwersji time_twartości na ciągi czytelne dla człowieka.
Keith Thompson,

12

Ma obsługiwać znaczniki czasu i daty sprzed 1 stycznia 1970 r.


1
To tylko 68 lat wstecz - 1902. To wydaje się całkiem sporo.
Bakudan

2
POSIX nie wymaga time_ttylko 32 bitów; to już 64 bity na wielu systemach.
Keith Thompson,

1
mktime()funkcja zwraca -1w przypadku błędu, więc prawdopodobnie nie jest możliwe rozróżnienie między poprawnymi znacznikami czasu sprzed 1970-01-01 a błędem ts. Daty niezgodności przed 01.01.1701 są zabronione
DimG

@DimG: Trudno jest odróżnić błąd od konkretnego znacznika czasu 1969-12-31 23:59:59 UTC. Wartość ujemna inna niż -1jest jednoznaczna.
Keith Thompson

1
@mtraceur: Standard C nie wymaga nieudanego mktime()wywołania do ustawienia errno. (POSIX robi.)
Keith Thompson
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.