1

如何mktime64()在 Linux 中使用 32 位时间库来避免 2038 年问题?

我们尝试使用宏_Time64但失败了,因为编译器仍然抛出未定义的mktime64()错误:

typedef long long _Time64_t;

_Time64_t _Time64(_Time64_t *pt);

struct tm *_Localtime64(_Time64_t *pt);

_Time64_t _mktime64(_Time64_t pt);

main.c:(.text+0x68): undefined reference to `_mktime64'

您能帮我如何使用 32 位库中的mktime64,time64和函数吗?localtime64

4

2 回答 2

2

Linux 上的C 标准库 ( CRT ) 只有一种time_t类型,所以没有_mktime64适合你的

在 32 位 Windows 上,有 2 种不同time_t类型 ( __time32_tand__time64_t ) 和 2 个版本的每个 time 函数 (如_mktime32and_mktime64 ) 只是因为 Microsoft在不破坏旧代码的情况下逐渐将 64 位时间支持添加到其 CRT中。标准标识符如time_tormktime实际上是宏,将被定义为所需的 32 位或 64 位版本。time_t在 VS2015 中默认更改为 64 位,因此从那时起编译的所有应用程序都不会受到 2038 年问题的影响。欲了解更多信息,请阅读另一个看 2038 年问题


time_tLinux CRT 通过立即更改为 64 位类型来解决 2038 年问题,而无需任何渐进的中间步骤。这发生在在 Linux 内核 5.6 或更高版本上运行的 32 位 glibc 2.32+ 和 musl 1.2+ 中。因此,为了避免在 32 位 Linux 上出现 2038 年问题,您必须使用足够新的内核和 CRT

  • 所有用户空间都必须使用 64 位编译,time_t即将到来的 musl-1.2 和 glibc-2.32 版本以及已安装的 linux-5.6 或更高版本的内核头文件将支持该版本。
  • 直接使用系统调用接口的应用程序需要移植以使用time64linux-5.1 中添加的系统调用来代替现有的系统调用。这会影响大多数用户futex()以及seccomp()拥有自己的运行时环境而不基于 libc 的编程语言。

https://lkml.org/lkml/2020/1/29/355?anz=web

如果您无法升级 CRT 和内核版本,那么您需要使用evalEmpire/y2038 之类的 3 rd方库

这是 POSIX time.h 的实现,它解决了 time_t 只有 32 位的系统上的 2038 年错误。它是在沼泽标准 ANSI C 中实现的。

如果您的内核版本介于 5.1 和 5.6 之间,那么您也可以编写自己的包装函数,因为在 32 位平台上的 64 位时间支持被引入 Linux 5.1 内核并添加了新的*time64系统调用

欲了解更多信息,请阅读

于 2020-12-11T15:28:10.157 回答
0

这些功能似乎只有微软

于 2019-10-23T06:33:47.307 回答