如果 C++ 中的 sizeof(std::time_t) == sizeof(std::uint64_t) 是否保证 2038 安全?

xml*_*lmx 5 c++ time standards y2k year2038

摘自cppref

std::time_t32 位有符号整数的实现(许多历史实现)将在 2038 年失败。

但是,文档没有说明如何检测当前实现是否是 2038 安全的。所以,我的问题是:

如果在 C++ 中,是否保证 2038 安全 sizeof(std::time_t) == sizeof(std::uint64_t)

phu*_*clv 1

实际上来说是的。在主要操作系统的所有现代实现中,time_t是自 POSIX 纪元以来的秒数,因此如果time_t大于int32_t则它不受 y2038 问题的影响

您还可以检查是否__USE_TIME_BITS64在 32 位 Linux 中定义以及是否_USE_32BIT_TIME_T在 32 位 Windows 中定义,以了解它是否是 2038 安全的


然而对于 C++ 标准,事情就没那么简单了。time_tC++中的定义与C标准中的内容<ctime>相同。在 C 中没有定义任何格式<time.h>time_t

3. 声明的类型为( 7.19size_t中描述);

clock_t
Run Code Online (Sandbox Code Playgroud)

time_t
Run Code Online (Sandbox Code Playgroud)

它们是能够代表时间的真实类型;

clock_t4.和中表示的时间范围和精度time_t是实现定义的

http://port70.net/~nsz/c/c11/n1570.html#7.27.1p3

因此,某些实现允许存储double1/1time_t年 16383 BCE 的皮秒,甚至是仅具有 32 个值位和 32 个填充位的 64 位整数。difftime()这可能是返回双倍的原因之一

要在运行时检查 y2038 问题,您可以使用mktime

mktime函数返回编码为 类型值的指定日历时间time_t。如果无法表示日历时间,则该函数返回值(time_t)(-1)

http://port70.net/~nsz/c/c11/n1570.html#7.27.2.3p3

struct tm time_str;
time_str.tm_year   = 2039 - 1900;
time_str.tm_mon    = 1 - 1;
time_str.tm_mday   = 1;
time_str.tm_hour   = 0;
time_str.tm_min    = 0;
time_str.tm_sec    = 1;
time_str.tm_isdst = -1;
if (mktime(&time_str) == (time_t)(-1))
    std::cout << "Not y2038 safe\n";
Run Code Online (Sandbox Code Playgroud)