2038,又一个世界末日?

UNIX时间,或称POSIX时间是UNIX或类UNIX系统使用的时间表示方式:从协调世界时1970年1月1日0时0分0秒起至现在的总秒数,不包括闰秒。

UNIX时间以自1970年1月1日经过的秒数(忽略闰秒)来表示时间,用time_t ()表示。


time_t定义如下:

// /usr/include/time.h
typedef __time_t time_t;

// fedora 18 x86_64
// /usr/include/x86_64-linux-gnu/bits/types.h
__STD_TYPE __TIME_T_TYPE __time_t;      /* Seconds since the Epoch.  */

// /usr/include/x86_64-linux-gnu/bits/typesizes.h
#define __TIME_T_TYPE           __SLONGWORD_TYPE

// /usr/include/x86_64-linux-gnu/bits/types.h
#define __SLONGWORD_TYPE        long int

可以看到time_t 实际类型为long int

在常用的32位系统中为4个字节

在64位系统中为8个字节


由于time_t类型大小的限制,导致能够表示的时间有限。

用以下代码进行测试

#include 
#include 
#include 

int main()
{
    time_t mint = 0;
    printf("min time_t: %s", ctime(&mint));
    printf("min time_t: %s", asctime(gmtime(&mint)));
    
    time_t maxt = INT_MAX;
    printf("max time_t: %s", ctime(&maxt));
    printf("max time_t: %s", asctime(gmtime(&maxt)));
    
    time_t curt;
    time(&curt);
    printf("current time: %s", ctime(&curt));
    printf("current time: %s", asctime(gmtime(&curt)));
    
    double dift = difftime(maxt, curt);
    printf("diff of maxt and curt: %.0f s", dift);
    
    time_t overt = INT_MAX + 1;
    printf("overflow time_t: %s", ctime(&overt));
    printf("overflow time_t: %s", asctime(gmtime(&overt)));
    
    return 0;
}

结果为:

min time_t: Thu Jan  1 08:00:00 1970
min time_t: Thu Jan  1 00:00:00 1970
max time_t: Tue Jan 19 11:14:07 2038
max time_t: Tue Jan 19 03:14:07 2038
current time: Tue Apr  8 05:32:47 2014
current time: Mon Apr  7 21:32:47 2014
diff of maxt and curt: 750577280 s
overflow time_t: Sat Dec 14 04:51:49 1901
overflow time_t: Fri Dec 13 20:45:52 1901

可以看到,起始时间为 1970年1月1日0时0分0秒

而,最大记录时间为2038年1月19日3时14分07秒(星期二)!!!

超过此时间,就回到了1901年……


time_t格式能表示的最后时间是2038年1月19日3时14分07秒(星期二)(UTC)

超过这一瞬间,时间将会“绕回”(wrap around)且在内部被表示为一个负数,并造成程序无法工作,因为它们无法将此时间识别为2038年,而可能会依个别实现而跳回1970年或1901年。


而64位的最后时间约2900亿年后的292,277,026,596年12月4日15:30:08,星期日

期待在2038年之前,完成系统架构的更新吧。

毕竟当年名噪一时的“千年虫”(Y2K)问题,也没有引起多大的波澜。

你可能感兴趣的:(科技)