简体   繁体   English

64 位 Unix 时间戳转换

[英]64-bit Unix timestamp conversion

Is there any C++ implementation of 64-bit Unix timestamp conversions for 32-bit systems?对于 32 位系统,是否有任何 C++ 实现 64 位 Unix 时间戳转换? I need to convert struct tm to 64-bit integer and vice versa, including leap years, time zones, UTC.我需要将struct tm转换为 64 位整数,反之亦然,包括闰年、时区、UTC。 Also need it portable, at least for GNU/Linux and Windows.还需要它可移植,至少对于 GNU/Linux 和 Windows。

You need:你需要:

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

Originally (in 2011) this answer contained links to 2038bug.com where it was possible to download the small pivotal_gmtime_r library, containing the mentioned functions.最初(在 2011 年)这个答案包含指向 2038bug.com 的链接,在那里可以下载包含上述函数的小型pivotal_gmtime_r库。 The library has been removed from 2038bug.com back then, the links became broken and were removed from the answer by a moderator.该库当时已从 2038bug.com 中删除,链接已损坏并被版主从答案中删除。 Seems like that pivotal_gmtime_r code can now be found here:似乎现在可以在这里找到pivotal_gmtime_r代码:

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

Also, I've found another, more recent library, called y2038 , that also implements mktime64 and localtime64_r :另外,我发现了另一个更新的库,名为y2038 ,它也实现了mktime64localtime64_r

https://github.com/evalEmpire/y2038 https://github.com/evalEmpire/y2038

The function converting a struct tm* to a time_t is mktime .struct tm*转换为time_t的函数是mktime You can find many implementations of it, eg.您可以找到它的许多实现,例如。 in Glibc and in libvxc's mktime.c file .在 Glibc 和libvxc 的mktime.c文件中 You could take the code (assuming it is legal to you, so please respect licenses) and change time_t to some 64 bits integer like int64_t .您可以使用代码(假设它对您是合法的,因此请尊重许可证)并将time_t更改为一些 64 位整数,例如int64_t

The functions doing the other conversions from time_t to struct tm* are localtime or gmtime and you could do likewise.执行从time_tstruct tm*的其他转换的函数是localtimegmtime ,您也可以这样做。

However, you might have a more fundamental issue: your 32 bits machine running in the year 2040 should have some way of giving you the current time (as the time system call does) appropriately in the 64 bits variant of time_t , and that is much harder (it depends upon the kernel and the hardware).但是,您可能有一个更基本的问题:您在 2040 年运行的 32 位机器应该有某种方式在time_t的 64 位变体中适当地为您提供当前时间(如time系统调用所做的那样),这是很多更难(这取决于内核和硬件)。

You seem to be making the assumption that time_t is 32-bits on 32-bit systems, and this may or may not be true.您似乎假设time_t在 32 位系统上是 32 位,这可能是也可能不是。

On Windows, starting with Visual Studio 2005 the size of time_t is 64-bits, even when you compile for 32-bit Windows.在 Windows 上,从 Visual Studio 2005 开始, time_t的大小为 64 位,即使您为 32 位 Windows 编译也是如此。

The unfortunate part is that glibc defines it as long int , which on 32-bit systems is a 32-bit integer.不幸的是,glibc 将其定义为long int ,在 32 位系统上是 32 位整数。 That means that 32-bit Linux and other 32-bit platforms that are based on gcc/glibc (like Cygwin) will not be able to work with 64-bit timestamps.这意味着 32 位 Linux 和其他基于 gcc/glibc(如 Cygwin)的 32 位平台将无法使用 64 位时间戳。

If your application must run on 32-bit glibc, then you should use your own conversion functions, which could be the same functions in the C library recompiled to use 64-bit timestamps.如果您的应用程序必须在 32 位 glibc 上运行,那么您应该使用自己的转换函数,这些函数可以是重新编译为使用 64 位时间戳的 C 库中的相同函数。

If you need source code with a permissive license (BSD), then you can look at these functions in minix3.如果您需要具有许可许可证 (BSD) 的源代码,那么您可以在 minix3 中查看这些功能。 Here is localtime. 这里是当地时间。 The source is hyperlinked, so you can find the others easily.来源是超链接的,因此您可以轻松找到其他来源。

64-bit time support on 32-bit Linux was first introduced in the 5.1 kernel with the addition of the new *time64 syscalls (because changing the return type of old system calls breaks old applications). 5.1 内核中首次引入了32 位 Linux 上的 64 位时间支持,并添加了新的*time64系统调用(因为更改旧系统调用的返回类型会破坏旧应用程序)。 Check this table and you'll see that those syscalls are only available on 32-bit platforms.查看此表,您将看到这些系统调用仅在 32 位平台上可用。

But that's only support from the kernel side.但这只是来自内核方面的支持。 You can call clock_gettime64 directly (from inline assembly, or from C with syscall() function) to get the current time but you'll need Linux-specific code because there's no glibc support yet.您可以直接调用clock_gettime64 (从内联汇编,或从 C 使用syscall()函数)来获取当前时间,但您需要特定于 Linux 的代码,因为还没有 glibc 支持。 For full userspace support you must be on Linux 5.6 or higher along with musl 1.2+ or glibc 2.32+.要获得完整的用户空间支持,您必须使用Linux 5.6 或更高版本以及 musl 1.2+ 或 glibc 2.32+。 Just rebuild your code and time_t will become 64-bit long.只需重建您的代码, time_t就会变成 64 位长。 Now code that uses time_t will become completely portable现在使用time_t代码将变得完全可移植

  • All user space must be compiled with a 64-bit time_t , which will be supported in the coming musl-1.2 and glibc-2.32 releases, along with installed kernel headers from linux-5.6 or higher.所有用户空间都必须使用 64 位time_t编译,即将发布的 musl-1.2 和 glibc-2.32 版本以及来自 linux-5.6 或更高版本的已安装内核头文件将支持该版本。

  • Applications that use the system call interfaces directly need to be ported to use the time64 syscalls added in linux-5.1 in place of the existing system calls.直接使用系统调用接口的应用程序需要移植以使用 linux-5.1 中添加的time64系统调用来代替现有的系统调用。 This impacts most users of futex() and seccomp() as well as programming languages that have their own runtime environment not based on libc.这会影响futex()seccomp()大多数用户以及拥有自己的不基于 libc 的运行时环境的编程语言。

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

For more information read欲了解更多信息,请阅读

Yeah use stuct tm *_localtime64 ( const __time64_t *timer);是的,使用stuct tm *_localtime64 ( const __time64_t *timer);

That's if your windows fan.那是如果你的窗户风扇。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM