Mengapa Unix menyimpan stempel waktu dalam bilangan bulat yang ditandatangani?

24

Mengapa integer yang ditandatangani digunakan untuk mewakili cap waktu? Ada awal yang jelas pada tahun 1970 yang direpresentasikan sebagai 0, jadi mengapa kita perlu angka sebelum itu? Apakah cap waktu negatif digunakan di mana saja?

Bakudan
sumber
2
Itu sebabnya Nostradamus tidak bisa menggunakan komputernya untuk menulis prediksi untuk tahun 3000 + ... itu akan menyebabkan overflow dan menunjukkan tanggalnya sebagai negatif. Saya pikir mereka menyebutnya bug Y3K atau sesuatu!
Jeach
3
Bangsa Romawi kuno bahkan memiliki masalah yang lebih buruk ketika angka tahun berubah dari negatif ke positif. Mereka akan menyebutnya masalah Y0K jika mereka punya cara untuk mengekspresikan angka nol. 8-)}
Keith Thompson

Jawaban:

35

Versi awal C tidak memiliki bilangan bulat yang tidak ditandatangani. (Beberapa programmer menggunakan pointer ketika mereka membutuhkan aritmatika unsigned.) Saya tidak tahu mana yang lebih dulu, time()fungsi atau tipe unsigned, tapi saya menduga representasi dibuat sebelum tipe unsigned tersedia secara universal. Dan 2038 sudah cukup jauh di masa depan yang mungkin tidak perlu dikhawatirkan. Saya ragu banyak orang mengira Unix masih akan ada saat itu.

Keuntungan lain dari yang ditandatangani time_tadalah bahwa memperluasnya menjadi 64 bit (yang sudah terjadi pada beberapa sistem) memungkinkan Anda mewakili waktu beberapa ratus miliar tahun ke depan tanpa kehilangan kemampuan untuk mewakili waktu sebelum tahun 1970. (Itulah mengapa saya menentang beralih ke 32-bit unsigned time_t ; kami memiliki cukup waktu untuk beralih ke 64 bit.)

Keith Thompson
sumber
7
The timeFungsi lebih tua dari zaman yang: Unix v1 (tahun 1971) dihitung dalam satuan 1 / 60th per detik, dari tengah malam pada 1971/01/01. Sudah diketahui bug bahwa “Pengguna yang berpikiran kronologis akan mencatat bahwa 2 ** 32 enam puluh asecond hanya sekitar 2,5 tahun.” unsigned Diperkenalkan oleh K&R pada 1978 , jauh setelah era 1970 didirikan.
Gilles 'SO- stop being evil'
Saya melakukan tes cepat dan pada kotak linux 64-bit saya. gmtimedan localtimemaks pada tahun 2147483647 (dengan detik berikutnya setelah memberikan -2147483648 sebagai tahun). Jadi, untuk melewati 55 bit waktu seseorang harus memperbarui rutinitas output untuk menggunakan int 64-bit untuk tahun ini alih-alih int 32-bit yang tidak ditandatangani. Mudah-mudahan seseorang akan menangani bug itu dalam beberapa miliar tahun mendatang.
freiheit
@freiheit: Menarik. Masalahnya adalah bahwa struct tmjenis memiliki anggota tm_year(mewakili tahun sejak 1900) yang bertipe int. Sistem 64-bit dapat dengan mudah memiliki 64-bit time_t, tetapi mereka biasanya memiliki 32-bit int. (Jika char8 bit dan int64 bit, maka shortbisa 16 atau 32 bit, dan tidak akan ada tipe yang telah ditentukan untuk ukuran lainnya.) Tetapi time()mungkin satu-satunya fungsi di dalamnya <time.h>yang benar-benar memerlukan dukungan level sistem; Anda dapat menulis kode Anda sendiri untuk mengonversi time_tnilai ke string yang dapat dibaca manusia.
Keith Thompson
12

Ini untuk mendukung cap waktu dan tanggal sebelum 1 Januari 1970.

amphetamachine
sumber
1
Ini membuat hanya 68 tahun di masa lalu - 1902. Ini sepertinya cukup sedikit.
Bakudan
2
POSIX tidak time_tharus hanya 32 bit; sudah 64 bit pada banyak sistem.
Keith Thompson
1
mktime()fungsi kembali -1jika terjadi kesalahan sehingga mungkin tidak mungkin untuk membedakan antara cap waktu yang benar sebelum 1970-01-01 dan ts kesalahan. Tanggal rupanya sebelum 1970-01-01 dilarang
DimG
@ Dimg: Sulit untuk membedakan antara kesalahan dan cap waktu tertentu 1969-12-31 23:59:59 UTC. Nilai negatif selain -1tidak ambigu.
Keith Thompson
1
@ traceur: Standar C tidak memerlukan mktime()panggilan gagal untuk mengatur errno. (POSIX melakukannya.)
Keith Thompson