【问题标题】:Is it guaranteed to be 2038-safe if sizeof(std::time_t) == sizeof(std::uint64_t) in C++?如果 sizeof(std::time_t) == sizeof(std::uint64_t) 在 C++ 中,是否保证 2038 安全?
【发布时间】:2022-01-05 08:55:10
【问题描述】:

摘自cppref

std::time_t 是 32 位有符号整数的实现(很多 历史实现)在 2038 年失败。

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

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

【问题讨论】:

  • (from : en.cppreference.com/w/cpp/chrono/c/time_t) 虽然没有定义,但它几乎总是一个整数值,保存自 1970 年 1 月 1 日 00:00 UTC 以来的秒数(不计算闰秒),对应于 POSIX 时间。 这不是我想要构建我的软件的定义,而是更喜欢使用 std::chrono。我认为您真正的问题是:我们可以通过编译为 64 位来避免重构我们的代码吗?我的建议是为您的时间处理内容编写单元测试,并专门针对跨越 2038 年问题点的日期和时间段对其进行测试。
  • 你想跨平台兼容吗?如果不是,则阅读相关平台的文档。

标签: c++ time standards year2038 y2k


【解决方案1】:

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

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


但是,对于 C++ 标准,事情并不那么简单。 C++ 中的time_t 定义在<ctime> 中,它具有C 标准中的same content as <time.h>。而在 C 中,time_t 没有被定义为任何格式

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

clock_t

time_t

哪些是能够表示时间的实数类型;

4。 clock_ttime_t 中可表示的时间范围和精度是实现定义的

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

因此,某些实现允许例如将 double 用作 time_t 并从公元前 16383 年的 1/1 年开始存储皮秒,甚至是只有 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";

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-13
    • 2016-04-27
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 2020-02-18
    • 2019-10-18
    • 2020-01-06
    相关资源
    最近更新 更多