64位Unix时间戳转换

问题描述 投票:0回答:5

是否有针对 32 位系统的 64 位 Unix 时间戳转换的 C++ 实现?我需要将

struct tm
转换为 64 位整数,反之亦然,包括闰年、时区、UTC。还需要它是可移植的,至少对于 GNU/Linux 和 Windows 而言。

c++ linux 64-bit 32bit-64bit time-t
5个回答
14
投票

您需要:

typedef long long time64_t; 
time64_t mktime64(struct tm *t); 
struct tm* localtime64_r(const time64_t* t, struct tm* p);

最初(2011 年)这个答案包含 2038bug.com 的链接,可以在其中下载包含上述功能的小型

pivotal_gmtime_r
库。当时该库已从 2038bug.com 中删除,链接已损坏并被版主从答案中删除。看起来
pivotal_gmtime_r
代码现在可以在这里找到:

https://github.com/franklin373/mortage/tree/master/time_pivotal

此外,我还发现了另一个更新的库,名为

y2038
,它也实现了
mktime64
localtime64_r

https://github.com/evalEmpire/y2038


7
投票

struct tm*
转换为
time_t
的函数是
mktime
。您可以找到它的许多实现,例如。在 Glibc 和 libvxc 的
mktime.c
文件
中。您可以获取代码(假设它对您来说是合法的,因此请尊重许可证)并将
time_t
更改为某个 64 位整数,例如
int64_t

执行从

time_t
struct tm*
的其他转换的函数是
localtime
gmtime
,您也可以这样做。

但是,您可能会遇到一个更根本的问题:在 2040 年运行的 32 位机器应该有某种方式以

time
的 64 位变体形式适当地为您提供当前时间(如
time_t
系统调用所做的那样) ,这要困难得多(这取决于内核和硬件)。


6
投票

您似乎假设

time_t
在 32 位系统上是 32 位,这可能是真的,也可能不是。

在 Windows 上,从 Visual Studio 2005 开始,

time_t
的大小为 64 位,即使针对 32 位 Windows 进行编译也是如此。

不幸的是 glibc 将其定义为

long int
,在 32 位系统上是一个 32 位整数。这意味着 32 位 Linux 和其他基于 gcc/glibc(如 Cygwin)的 32 位平台将无法使用 64 位时间戳。

如果您的应用程序必须在 32 位 glibc 上运行,那么您应该使用自己的转换函数,这些函数可以是重新编译为使用 64 位时间戳的 C 库中的相同函数。

如果您需要具有许可许可证(BSD)的源代码,那么您可以在 minix3 中查看这些函数。 这里是当地时间。来源有超链接,因此您可以轻松找到其他来源。


0
投票

32 位 Linux 上的 64 位时间支持首次在 5.1 内核中引入,并添加了新的 *time64

 系统调用
(因为更改旧系统调用的返回类型会破坏旧应用程序) 。检查此表,您将看到这些系统调用仅在 32 位平台上可用。

但这只是内核方面的支持。您可以直接调用

clock_gettime64

(从内联汇编,或从 C 语言使用 
syscall()
 函数)来获取当前时间,但您需要 Linux 特定的代码,因为尚不支持 glibc。要获得完整的
用户空间支持,您必须使用Linux 5.6或更高版本以及musl 1.2+或glibc 2.32+。只需重建您的代码,time_t
就会变成 64 位长。现在使用 
time_t
 的代码将变得完全可移植

  • 所有用户空间都必须使用 64 位

    time_t

     进行编译,即将推出的 musl-1.2 和 glibc-2.32 版本以及 linux-5.6 或更高版本中安装的内核头文件将支持该版本。

  • 直接使用系统调用接口的应用程序需要移植以使用linux-5.1中添加的

    time64

    系统调用来代替现有的系统调用。这会影响 
    futex()
    seccomp()
     的大多数用户以及拥有自己的运行时环境但不基于 libc 的编程语言。

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

也就是说,即使您使用较新的 glibc,您可能仍然需要在各种情况下构建自己的库

正如 Debian 在过渡时所说的那样

glibc 2.34 支持现有的 32 位 ABI/API 和新的 64 位 ABI/API。但是,它不提供强制使用新 API/ABI 的开关 - 每个构建/包都明确选择使用 64 位 API/ABI(通过设置

_TIME_BITS=64

)。这对于 Debian 来说是一个问题,因为在正常的过渡中,我们期望简单地针对新库进行构建就能获得新的 ABI。有些东西(glibc、dpkg、gcc?)必须说“默认使用 64 位时间”。 
1030159 已实现 DEB_BUILD_OPTIONS=abi=+time64
 选项作为一致的 Debian 机制。

欲了解更多信息,请阅读

  • 接近2038年内核终局游戏
  • 讨论如何解决
  • Y2038问题2038比看起来更近
  • GNU C 库中的 64 位时间符号处理
  • glibc Y2038 验证设计
  • 将time_t和clock_t更改为64位

-1
投票
是的,使用

stuct tm *_localtime64 ( const __time64_t *timer);



那就是如果你的窗户风扇。

© www.soinside.com 2019 - 2024. All rights reserved.