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.
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 standardtime()
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
jakosigned 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 typytime_t
są podatne na problem roku 2038.
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
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
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?
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ę.
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
.
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;
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.
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.
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);
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
.
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