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

typedef __time_t time_t;

但是我找不到__time_t的定义。


当前回答

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

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

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

其他回答

[根]#猫时间

#include <time.h>

int main(int argc, char** argv)
{
        time_t test;
        return 0;
}

[root]# gcc -E time.c | grep __time_t .c

类型定义long int __time_t;

它在$INCDIR/bits/types.h中定义:

# 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

您可以使用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

在Visual Studio 2008中,它默认为__int64,除非你定义了_USE_32BIT_TIME_T。最好是假装不知道它的定义,因为它可以(也将)在不同平台之间改变。

time_t维基百科的文章给出了一些解释。归根结底,在C规范中,time_t的类型是不保证的。

The time_t datatype is a data type in the ISO C library defined for storing system time values. Such values are returned from the standard time() library function. This type is a typedef defined in the standard header. ISO C defines time_t as an arithmetic type, but does not specify any particular type, range, resolution, or encoding for it. Also unspecified are the meanings of arithmetic operations applied to time values. Unix and POSIX-compliant systems implement the time_t type as a signed integer (typically 32 or 64 bits wide) which represents the number of seconds since the start of the Unix epoch: midnight UTC of January 1, 1970 (not counting leap seconds). Some systems correctly handle negative time values, while others do not. Systems using a 32-bit time_t type are susceptible to the Year 2038 problem.

在大多数传统平台上,它是一个32位有符号整数类型。然而,这会导致您的代码遭受2038年的错误。因此,现代C库应该将其定义为有符号的64位整型,这在几十亿年里是安全的。