我搜索我的Linux盒子,看到这样的类型定义:

typedef __time_t time_t;

但是我找不到__time_t的定义。


当前回答

您可以使用typeid来找出time_t在您的系统中是如何定义的。

#include <iostream> // cout
#include <ctime>    // time_t
#include <typeinfo> // typeid, name

using namespace std;

int main()
{
    cout << "Test 1: The type of time_t is: \t\t" 
         << typeid(time_t).name() << endl;
    cout << "Test 2: time_t is a signed long?: \t"
         << (typeid(time_t) == typeid(signed long) ? "true" : "false") << endl;
    cout << "Test 3: time_t is an unsigned long?: \t" 
         << (typeid(time_t) == typeid(unsigned long) ? "true" : "false") << endl;
    return 0;
}

在我的系统中,输出是:

Test 1: The type of time_t is:          l
Test 2: time_t is a signed long?:       true
Test 3: time_t is an unsigned long?:    false

其他回答

time_t只是8字节的类型定义(long long/__int64),所有编译器和操作系统都理解。在过去,它只用于长int(4字节),但现在不是了。如果你查看crtdef .h中的time_t,你会发现这两种实现,但操作系统将使用long long。

在64位机器上,Time_t的类型为long int,否则为long long int。

你可以在这些头文件中验证这一点:

time.h: /usr/include Types.h和typeszes .h: /usr/include/x86_64-linux-gnu/bits

(下面的陈述不是一个接一个的。他们可以在答复中找到。头文件使用Ctrl+f搜索。)

1)在time.h

typedef __time_t time_t;

2)在types.h

# define __STD_TYPE     typedef  
__STD_TYPE __TIME_T_TYPE __time_t;  

3)在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)再次在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;

通常,您将在bits或asm头目录中找到这些用于gcc的底层实现特定的typedefs。对我来说,是/usr/include/x86_64-linux-gnu/bits/types.h。

您可以只使用grep,或者使用Quassnoi建议的预处理器调用来查看哪个特定的头文件。

您可以使用typeid来找出time_t在您的系统中是如何定义的。

#include <iostream> // cout
#include <ctime>    // time_t
#include <typeinfo> // typeid, name

using namespace std;

int main()
{
    cout << "Test 1: The type of time_t is: \t\t" 
         << typeid(time_t).name() << endl;
    cout << "Test 2: time_t is a signed long?: \t"
         << (typeid(time_t) == typeid(signed long) ? "true" : "false") << endl;
    cout << "Test 3: time_t is an unsigned long?: \t" 
         << (typeid(time_t) == typeid(unsigned long) ? "true" : "false") << endl;
    return 0;
}

在我的系统中,输出是:

Test 1: The type of time_t is:          l
Test 2: time_t is a signed long?:       true
Test 3: time_t is an unsigned long?:    false

答案肯定是特定于实现的。为了确定你的平台/编译器,只需要在你的代码中添加这个输出:

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

如果答案是4(32位),而你的数据意味着超过2038年,那么你有25年的时间来迁移你的代码。

如果你将数据存储为字符串,你的数据将会很好,即使它是一些简单的东西,如:

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

然后以同样的方式将其读入(fread, fscanf等读入int类型),就得到了纪元偏移时间。在. net中也存在类似的解决方案。我在Win和Linux系统之间传递64位的历元号没有问题(通过通信通道)。这会带来字节排序问题,但这是另一个主题。

为了回答paxdiablo的问题,我会说它打印了“19100”,因为程序是这样写的(我承认我自己在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);

printf语句输出固定字符串“Year is: 19”,后面跟着一个由零填充的字符串“years since 1900”(tm->tm_year的定义)。在2000年,这个值显然是100。“%02d”填充两个零,但如果长度超过两个数字,则不会截断。

正确的方法是(只修改到最后一行):

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

新问题:这种想法的基本原理是什么?