Jawaban:
The time_t artikel Wikipedia Artikel memberi petunjuk pada ini. Intinya adalah bahwa jenis time_ttidak dijamin dalam spesifikasi C.
Tipe
time_tdata adalah tipe data dalam pustaka ISO C yang didefinisikan untuk menyimpan nilai waktu sistem. Nilai-nilai tersebut dikembalikan daritime()fungsi perpustakaan standar . Tipe ini adalah typedef yang didefinisikan dalam header standar. ISO C mendefinisikan time_t sebagai tipe aritmatika, tetapi tidak menentukan tipe , rentang, resolusi, atau penyandian tertentu untuk itu. Juga tidak ditentukan adalah arti operasi aritmatika yang diterapkan pada nilai waktu.Sistem Unix dan POSIX-compliant menerapkan
time_ttipe sebagai asigned integer(biasanya lebar 32 atau 64 bit) yang mewakili jumlah detik sejak dimulainya zaman Unix : tengah malam UTC 1 Januari 1970 (tidak termasuk detik kabisat). Beberapa sistem dengan benar menangani nilai waktu negatif, sementara yang lain tidak. Sistem yang menggunakan tipe 32-bittime_trentan terhadap masalah Tahun 2038 .
time_tdalam struktur data pada disk dapat terjadi. Namun, karena filesystem sering dibaca oleh sistem operasi lain, itu akan konyol untuk mendefinisikan filesystem berdasarkan pada jenis tergantung implementasi. Sebagai contoh, sistem file yang sama dapat digunakan pada sistem 32-bit dan 64-bit, dan time_tmungkin berubah ukuran. Dengan demikian, filesystem perlu didefinisikan secara lebih tepat ("integer bertanda 32-bit yang memberikan jumlah detik sejak awal 1970, dalam UTC") daripada hanya sebagai time_t.
time.hkonten. Artikel itu terhubung ke cppreference.com tetapi konten yang dikutip tidak ditemukan ...
time_tditandatangani tidak benar. pubs.opengroup.org/onlinepubs/9699919799/basedefs/… menyatakan bahwa berbagai hal harus berupa "tipe integer yang ditandatangani" atau "tipe integer yang tidak ditandatangani", tetapi time_thanya dikatakan bahwa itu "akan menjadi tipe integer" . Implementasi dapat membuat time_tunsigned dan masih kompatibel dengan POSIX.
[root]# cat time.c
#include <time.h>
int main(int argc, char** argv)
{
time_t test;
return 0;
}
[root]# gcc -E time.c | grep __time_t
typedef long int __time_t;
Ini didefinisikan $INCDIR/bits/types.hmelalui:
# 131 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/typesizes.h" 1 3 4
# 132 "/usr/include/bits/types.h" 2 3 4
typedef __int32_t __time_t;dan typedef __time_t time_t;dalam a FreeBSD freebsd-test 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #8: Sun Aug 7 18:23:48 UTC 2011 root@freebsd-test:/usr/obj/usr/src/sys/MYXEN i386. Hasil Anda secara eksplisit diatur seperti itu di Linux (setidaknya pada 2.6.32-5-xen-amd64 dari Debian).
__time_tdan tidak time_tmenemukan jenis yang mendasarinya time_t? Menghilangkan langkah?
typedef __time_t time_t;, pemeriksaan kode di sekitarnya juga diperlukan untuk memastikan bahwa typedef sebenarnya digunakan dan bukan hanya bagian dari kompilasi bersyarat. typedef long time_t;mungkin telah ditemukan juga.
Standar
William Brendel mengutip Wikipedia, tetapi saya lebih suka dari mulut kuda.
C99 N1256 draft standar 7.23.1 / 3 "Komponen waktu" mengatakan:
Tipe yang dideklarasikan adalah size_t (dijelaskan pada 7.17) clock_t dan time_t yang merupakan tipe aritmatika yang mampu merepresentasikan waktu
dan 6.2.5 / 18 "Jenis" mengatakan:
Tipe integer dan mengambang secara kolektif disebut tipe aritmatika.
POSIX 7 sys_types.h mengatakan:
[CX] time_t akan menjadi tipe integer.
mana [CX]yang didefinisikan sebagai :
[CX] Perpanjangan ke standar ISO C.
Ini adalah perpanjangan karena itu membuat jaminan yang lebih kuat: floating point keluar.
gcc one-liner
Tidak perlu membuat file seperti yang disebutkan oleh Quassnoi :
echo | gcc -E -xc -include 'time.h' - | grep time_t
Pada Ubuntu 15.10 GCC 5.2 dua baris teratas adalah:
typedef long int __time_t;
typedef __time_t time_t;
Command breakdown dengan beberapa kutipan dari man gcc:
-E: "Berhenti setelah tahap preprocessing; jangan jalankan compiler dengan benar."-xc: Tentukan bahasa C, karena input berasal dari stdin yang tidak memiliki ekstensi file.-include file: "Memproses file seolah" #include "file" "muncul sebagai baris pertama dari file sumber utama."-: masukan dari stdingcc -E -xc -include time.h /dev/null | grep time_t
Jawabannya jelas khusus untuk implementasi. Untuk mengetahui secara pasti untuk platform / kompiler Anda, cukup tambahkan output ini di suatu tempat dalam kode Anda:
printf ("sizeof time_t is: %d\n", sizeof(time_t));
Jika jawabannya adalah 4 (32 bit) dan data Anda dimaksudkan untuk melampaui 2038 , maka Anda memiliki 25 tahun untuk memigrasi kode Anda.
Data Anda akan baik-baik saja jika Anda menyimpan data Anda sebagai string, meskipun itu sesuatu yang sederhana seperti:
FILE *stream = [stream file pointer that you've opened correctly];
fprintf (stream, "%d\n", (int)time_t);
Kemudian baca saja kembali dengan cara yang sama (fread, fscanf, dll menjadi int), dan Anda memiliki waktu offset zaman Anda. Solusi serupa ada di. Net. Saya melewati nomor zaman 64-bit antara sistem Win dan Linux tanpa masalah (melalui saluran komunikasi). Itu memunculkan masalah pemesanan byte, tapi itu topik lain.
Untuk menjawab pertanyaan paxdiablo, saya akan mengatakan bahwa itu dicetak "19100" karena program ini ditulis dengan cara ini (dan saya akui saya melakukannya sendiri di tahun 80-an):
time_t now;
struct tm local_date_time;
now = time(NULL);
// convert, then copy internal object to our object
memcpy (&local_date_time, localtime(&now), sizeof(local_date_time));
printf ("Year is: 19%02d\n", local_date_time.tm_year);
The printfpernyataan mencetak string tetap "Tahun ini: 19" diikuti dengan string nol-empuk dengan "tahun sejak tahun 1900" (definisi tm->tm_year). Pada tahun 2000, nilai itu adalah 100, jelas. "%02d"bantalan dengan dua nol tetapi tidak terpotong jika lebih dari dua digit.
Cara yang benar adalah (ubah hanya ke baris terakhir):
printf ("Year is: %d\n", local_date_time.tm_year + 1900);
Pertanyaan baru: Apa alasan pemikiran itu?
%zupenentu format untuk memformat size_tnilai (seperti yang dihasilkan oleh sizeof), karena mereka tidak ditandatangani ( u) dan dengan panjang size_t ( z) ·
printf ("sizeof time_t is: %d\n", (int) sizeof(time_t));dan hindari zmasalah ini.
Di bawah Visual Studio 2008, itu default ke __int64kecuali Anda mendefinisikan _USE_32BIT_TIME_T. Anda lebih baik berpura-pura tidak tahu apa itu didefinisikan, karena itu dapat (dan akan) berubah dari platform ke platform.
time_tadalah tipe long intpada mesin 64 bit, selain itu long long int.
Anda dapat memverifikasi ini di file header ini:
time.h: /usr/include
types.hdan typesizes.h:/usr/include/x86_64-linux-gnu/bits
(Pernyataan di bawah ini tidak satu demi satu. Mereka dapat ditemukan di file header resp menggunakan pencarian Ctrl + f.)
1) Dalam time.h
typedef __time_t time_t;
2) Dalam types.h
# define __STD_TYPE typedef
__STD_TYPE __TIME_T_TYPE __time_t;
3) Dalam typesizes.h
#define __TIME_T_TYPE __SYSCALL_SLONG_TYPE
#if defined __x86_64__ && defined __ILP32__
# define __SYSCALL_SLONG_TYPE __SQUAD_TYPE
#else
# define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE
#endif
4) Lagi di types.h
#define __SLONGWORD_TYPE long int
#if __WORDSIZE == 32
# define __SQUAD_TYPE __quad_t
#elif __WORDSIZE == 64
# define __SQUAD_TYPE long int
#if __WORDSIZE == 64
typedef long int __quad_t;
#else
__extension__ typedef long long int __quad_t;
long intmana - mana. Lihat stackoverflow.com/questions/384502/…
Ini adalah tipe integer bertanda 32-bit pada sebagian besar platform lawas. Namun, itu menyebabkan kode Anda menderita bug tahun 2038 . Jadi perpustakaan C modern harus mendefinisikannya sebagai int 64-bit yang ditandatangani sebagai gantinya, yang aman untuk beberapa miliar tahun.
Biasanya Anda akan menemukan typedef khusus implementasi yang mendasari ini untuk gcc di direktori bitsatau asmheader. Bagi saya, ini/usr/include/x86_64-linux-gnu/bits/types.h .
Anda bisa saja grep, atau menggunakan doa preprocessor seperti yang disarankan oleh Quassnoi untuk melihat header tertentu.
Apa yang akhirnya menjadi typ timeef?
Kode yang kuat tidak peduli apa jenisnya.
Spesies C time_tmenjadi tipe nyata seperti double, long long, int64_t, int, dll.
Bahkan bisa unsignedsebagai nilai pengembalian dari banyak fungsi waktu menunjukkan kesalahan tidak -1, tetapi(time_t)(-1) - Pilihan implementasi ini tidak umum.
Intinya adalah bahwa "perlu tahu" jenisnya jarang. Kode harus ditulis untuk menghindari kebutuhan.
Namun "perlu tahu" yang umum terjadi ketika kode ingin mencetak mentah time_t. Casting ke tipe integer terluas akan mengakomodasi sebagian besar case modern.
time_t now = 0;
time(&now);
printf("%jd", (intmax_t) now);
// or
printf("%lld", (long long) now);
Casting ke doubleatau long doubleakan bekerja juga, namun bisa memberikan output desimal yang tidak tepat
printf("%.16e", (double) now);
double difftime(time_t time1, time_t time0)pendekatan pengurangan yang seragam.
time_thanya typedefuntuk 8 byte ( long long/__int64) yang dimengerti oleh semua kompiler dan OS. Kembali pada hari-hari, dulu hanya untuk long int(4 byte) tetapi tidak sekarang. Jika Anda melihat di time_tdalam crtdefs.hAnda akan menemukan kedua implementasi tetapi OS akan digunakan long long.
long int.