Co to jest ostatecznie czas t typedef do?

Szukałem w Linuksie i zobaczyłem, że jest wpisywane do

typedef __time_t time_t;

Ale nie można znaleźć definicji __time_T.

Author: BoltClock, 2009-01-23

10 answers

Artykuł time_t Wikipedii artykuł rzuca trochę światła na ten temat. Najważniejsze jest to, że typ time_t nie jest gwarantowany w specyfikacji C.

Typ danych time_t jest typem danych w biblioteka ISO C zdefiniowana do przechowywania wartości czasu systemowego. Takimi wartościami są returned from the standard time() funkcja biblioteczna. Ten typ to typedef zdefiniowany w standardzie nagłówek. ISO C definiuje time_t jako typ arytmetyczny, ale robi nie określa żadnych Typ szczególny , zakres, rozdzielczość lub kodowanie dla niego. Również nieokreślone są znaczenia operacje arytmetyczne stosowane w czasie wartości.

Systemy zgodne z Uniksem i POSIX implementują typ time_t jako signed integer (Zwykle o szerokości 32 lub 64 bitów) co oznacza liczbę sekund od początku epoki Uniksa : o północy UTC z 1 stycznia 1970 (Nie liczenie sekund przestępnych). Niektóre systemy prawidłowo obsługiwać ujemne wartości czasu, podczas gdy inni nie. Systemy wykorzystujące 32-bitowe typy time_t są podatne na problem roku 2038.

 150
Author: William Brendel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-13 07:51:10

[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;

Jest zdefiniowany w $INCDIR/bits/types.h poprzez:

# 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
 96
Author: Quassnoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-22 23:23:29

Standardy

William Brendel cytował Wikipedię, ale wolę to z paszczy konia.

C99 n1256 standard draft 7.23.1/3 "składniki czasu" mówi:

Typy deklarowane to size_t (opisane w 7.17) clock_t i time_t, które są typami arytmetycznymi zdolnymi do reprezentowania czasów

I 6.2.5 / 18"typy" says:

Typy całkowite i zmiennoprzecinkowe są zbiorczo zwane typami arytmetycznymi.

POSIX 7 sys_types.h mówi:

[CX] time_t jest typem całkowitym.

Gdzie [CX]jest zdefiniowane jako :

[CX] rozszerzenie do normy ISO C.

Jest to rozszerzenie, ponieważ daje silniejszą gwarancję: zmiennoprzecinkowe są wyłączone.

Gcc one-liner

Nie ma potrzeby tworzenia pliku jak wspomniano przez Quassnoi :

echo | gcc -E -xc -include 'time.h' - | grep time_t

On Ubuntu 15.10 GCC 5.2 dwie pierwsze linie to:

typedef long int __time_t;
typedef __time_t time_t;

Podział komendy z cytatami z man gcc:

  • -E: "Zatrzymaj się po etapie wstępnego przetwarzania; nie uruchom WŁAŚCIWEGO kompilatora."
  • -xc: określa język C, ponieważ wejście pochodzi ze standardowego wejścia, które nie ma rozszerzenia pliku.
  • -include file: "Process file as if" # include "file "" appeared as the first line of the primary source file."
  • -: Wejście ze stdin
 12
Author: Ciro Santilli 新疆改造中心 六四事件 法轮功,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-16 18:56:16

Odpowiedź jest zdecydowanie specyficzna dla implementacji. Aby definitywnie dowiedzieć się o swojej platformie / kompilatorze, po prostu dodaj to wyjście gdzieś w kodzie:

printf ("sizeof time_t is: %d\n", sizeof(time_t));

Jeśli odpowiedź wynosi 4 (32 bity) i Twoje dane mają wykraczać poza 2038, Następnie masz 25 lat na migrację kodu.

Twoje dane będą w porządku, jeśli przechowasz je jako ciąg znaków, nawet jeśli jest to coś prostego jak:

FILE *stream = [stream file pointer that you've opened correctly];
fprintf (stream, "%d\n", (int)time_t);

Następnie po prostu przeczytaj to w ten sam sposób (fread, fscanf, itp. do int), i masz swój czas przesunięcia epoki. Podobne obejście istnieje w .Net. przekazuję 64-bitowe numery epoch między systemami Win i Linux bez problemu (przez kanał komunikacyjny). To wywołuje problemy z porządkowaniem bajtów, ale to inny temat.

Odpowiadając na zapytanie paxdiablo, powiedziałbym, że Wydrukowano "19100", ponieważ program został napisany w ten sposób (i przyznaję, że sam to zrobiłem w latach 80-tych): {]}

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);

Instrukcja printf wyświetla stały ciąg znaków "Year is: 19", po którym następuje ciąg zerowy z "latami od 1900" (definicja tm->tm_year). W 2000 roku wartość ta wynosi oczywiście 100. "%02d" pola z dwoma zerami, ale nie obcinają się, jeśli są dłuższe niż dwie cyfry.

Poprawny sposób to (zmień tylko ostatnią linię):

printf ("Year is: %d\n", local_date_time.tm_year + 1900);

Nowe pytanie: Jakie są przesłanki takiego myślenia?

 11
Author: pwrgreg007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-14 16:37:15

W programie Visual Studio 2008 domyślnie jest to __int64, chyba że zdefiniujesz _USE_32BIT_TIME_T. Lepiej udawaj, że nie wiesz, jak to jest zdefiniowane, ponieważ może (i będzie) zmieniać się z platformy na platformę.

 7
Author: Eclipse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-22 23:21:31

time_t jest typu long int na maszynach 64-bitowych, inaczej jest long long int.

Możesz to sprawdzić w plikach nagłówkowych:

time.h: /usr/include
types.h oraz typesizes.h: /usr/include/x86_64-linux-gnu/bits

(poniższe stwierdzenia nie są jedno po drugim. Można je znaleźć w resp. plik nagłówka za pomocą Ctrl + F Szukaj.)

1)W time.h

typedef __time_t time_t;

2)W types.h

# define __STD_TYPE     typedef  
__STD_TYPE __TIME_T_TYPE __time_t;  

3)w 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) Ponownie w 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;
 5
Author: abcoep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 11:21:21

Jest to 32-bitowy, podpisany Typ liczby całkowitej na większości starszych platform. Jednak powoduje to, że Twój kod cierpi na błąd rok 2038 . Dlatego nowoczesne biblioteki C powinny definiować go jako podpisany 64-bitowy int, który jest Bezpieczny przez kilka miliardów lat.

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-22 23:26:37

Zazwyczaj znajdziesz te podstawowe dla implementacji typy dla gcc w katalogu nagłówkowym bits LUB asm. Dla mnie to /usr/include/x86_64-linux-gnu/bits/types.h.

Możesz po prostu grep lub użyć wywołania preprocesora , takiego jak sugerowane przez Quassnoi , aby zobaczyć, który konkretny nagłówek.

 3
Author: poolie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:33

Do czego ostatecznie należy Typ time_t?

Solidny kod nie obchodzi, jaki jest typ.

C gatunek time_t BYĆ prawdziwy typ Jak double, long long, int64_t, int itd.

Może być nawet unsigned, ponieważ wartości zwracane z funkcji many time wskazującej błąd nie są -1, ale (time_t)(-1) - ten wybór implementacji jest rzadki.

Chodzi o to, że "trzeba wiedzieć" typ jest rzadki. Kod powinien być napisany, aby uniknąć takiej potrzeby.


Jeszcze często spotykane "need-to-know" występuje, gdy KOD chce wydrukować raw time_t. Odlewanie do najszerszego typu integer pomieści większość nowoczesnych przypadków.

time_t now = 0;
time(&now);
printf("%jd", (intmax_t) now);
// or 
printf("%lld", (long long) now);

Casting do double lub long double też będzie działać, ale może dostarczyć inexact decimal output

printf("%.16e", (double) now);
 1
Author: chux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-04 21:44:48

time_t jest po prostu typedef dla 8 bajtów (long long/__int64), które rozumieją wszystkie kompilatory i system operacyjny. Kiedyś był tylko dla long int (4 bajty), ale nie teraz. Jeśli spojrzysz na time_t w crtdefs.h znajdziesz obie implementacje, ale system operacyjny użyje long long.

 0
Author: bvrwoo_3376,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-16 10:33:14