¿Qué es en última instancia un tiempo t typedef a?


Busqué en linux box y vi que estaba siendo typedef a

typedef __time_t time_t;

Pero no se pudo encontrar la definición _ _ time _ t.

Author: BoltClock, 2009-01-23

10 answers

El artículo time_t de Wikipedia arroja algo de luz sobre esto. La conclusión es que el tipo de time_t no está garantizado en la especificación C.

El tipo de datos time_t es un tipo de datos en la biblioteca ISO C definida para almacenar valores de tiempo del sistema. Tales valores son devuelto de la norma time() función de biblioteca. Este tipo es un typedef definido en el estándar cabecera. ISO C define time_t como un tipo aritmético, pero hace no se especifica ninguna tipo particular, rango, resolución o codificación para él. También no se especifican los significados de operaciones aritméticas aplicadas al tiempo valor.

Los sistemas compatibles con Unix y POSIX implementan el tipo time_t como un signed integer (normalmente de 32 o 64 bits de ancho) que representa el número de segundos desde el inicio de Unix epoch: medianoche UTC del 1 de enero de 1970 (no contando segundos intercalares). Algunos sistemas manejar correctamente los valores de tiempo negativos, mientras que otros lo hacen ni. Sistemas que utilizan un 32-bit time_t tipo son susceptibles a el problema del año 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
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;

Se define en $INCDIR/bits/types.h a través de:

# 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-22 23:23:29

Normas

William Brendel citó Wikipedia, pero lo prefiero de la boca del caballo.

C99 N1256 borrador estándar 7.23.1/3 "Componentes del tiempo" dice:

Los tipos declarados son size_t (descrito en 7.17) clock_t y time_t que son tipos aritméticos capaces de representar tiempos

Y 6.2.5 / 18"Tipos" dice:

Los tipos entero y flotante son colectivamente llamados tipos aritméticos.

POSIX 7 sys_types.h dice:

[CX] time_t será un tipo entero.

Donde [CX] se define como :

[CX] Extensión a la norma ISO C.

Es una extensión porque hace una garantía más fuerte: los puntos flotantes están fuera.

Gcc one-liner

No es necesario crear un archivo como se menciona por Quassnoi :

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

El Ubuntu 15.10 GCC 5.2 las dos primeras líneas son:

typedef long int __time_t;
typedef __time_t time_t;

Desglose de comandos con algunas citas de man gcc:

  • -E: "Deténgase después de la etapa de preprocesamiento; no ejecute el compilador propiamente."
  • -xc: Especifique el lenguaje C, ya que la entrada proviene de stdin que no tiene extensión de archivo.
  • -include file: "Procesar archivo como si "#incluir "archivo"" apareció como la primera línea del archivo fuente primario."
  • -: entrada de 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-16 18:56:16

La respuesta es definitivamente específica de la implementación. Para averiguar definitivamente para su plataforma/compilador, simplemente agregue esta salida en algún lugar de su código:

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

Si la respuesta es 4 (32 bits) y sus datos están destinados a ir más allá 2038, entonces tienes 25 años para migrar tu código.

Sus datos estarán bien si almacena sus datos como una cadena, incluso si es algo simple como:

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

Entonces solo léalo de nuevo de la misma manera (fread, fscanf, etc. en un int), y tienes tu tiempo de desplazamiento de época. Una solución similar existe en .Net. I pasa números epoch de 64 bits entre sistemas Win y Linux sin ningún problema (a través de un canal de comunicaciones). Eso trae problemas de orden de bytes, pero ese es otro tema.

Para responder a la pregunta de paxdiablo, diría que imprimió "19100" porque el programa fue escrito de esta manera (y admito que lo hice yo mismo en los años 80):

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

La instrucción printf imprime la cadena fija "Year is: 19" seguida de una cuerda acolchada cero con los "años desde 1900" (definición de tm->tm_year). En 2000, ese valor es 100, obviamente. "%02d" rellena con dos ceros pero no trunca si tiene más de dos dígitos.

La forma correcta es (cambiar a la última línea solamente):

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

Nueva pregunta: ¿Cuál es la razón de ser de ese pensamiento?

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-14 16:37:15

En Visual Studio 2008, el valor predeterminado es __int64 a menos que defina _USE_32BIT_TIME_T. Es mejor fingir que no sabes cómo se define, ya que puede (y cambiará) de plataforma en plataforma.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-22 23:21:31

time_t es de tipo long int en máquinas de 64 bits, de lo contrario es long long int.

Puede verificar esto en estos archivos de encabezado:

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

(Las siguientes declaraciones no son una tras otra. Podrían encontrarse en el resp. archivo de encabezado usando Ctrl + f buscar.)

1) En time.h

typedef __time_t time_t;

2) En types.h

# define __STD_TYPE     typedef  
__STD_TYPE __TIME_T_TYPE __time_t;  

3) En 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) De nuevo en 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-28 11:21:21

Es un tipo entero con signo de 32 bits en la mayoría de las plataformas heredadas. Sin embargo, eso hace que su código sufra del error año 2038. Por lo tanto, las bibliotecas C modernas deberían definirlo como un int de 64 bits firmado, lo que es seguro durante unos pocos miles de millones de años.

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

Normalmente encontrará estos typedefs subyacentes específicos de la implementación para gcc en el directorio de encabezado bits o asm. Para mí, es /usr/include/x86_64-linux-gnu/bits/types.h.

Puede simplemente grep, o usar una invocación de preprocesador como la sugerida por Quassnoi para ver qué encabezado específico.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:33

¿A qué es en última instancia un time_t typedef?

Al código robusto no le importa cuál sea el tipo.

C species time_t to be a real type like double, long long, int64_t, int, etc.

Incluso podría ser unsigned ya que los valores devueltos de la función de muchos tiempos que indican error no es -1, pero (time_t)(-1) - Esta opción de implementación es poco común.

El punto es que la "necesidad de saber", el tipo es raro. El código debe ser escrito para evitar la necesidad.


Aún una "necesidad de saber" común ocurre cuando el código quiere imprimir el raw time_t. La conversión al tipo entero más ancho acomodará la mayoría de los casos modernos.

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

Lanzar a un double o long double también funcionará, pero podría proporcionar inexacta salida decimal

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-04 21:44:48

time_t es solo typedef para 8 bytes (long long/__int64) que todos los compiladores y sistemas operativos entienden. Antes, solía ser solo para long int (4 bytes), pero ahora no. Si usted mira la time_t en crtdefs.h encontrará ambas implementaciones, pero el sistema operativo utilizará 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-16 10:33:14