24

在 32 位嵌入式 Linux (ARMLinux) 的 C 代码中处理时间的正确方法是什么,以确保代码在 2038 年 1 月 19 日 03:14:07 UTC 之后继续正常工作(当有符号的 32 位time_t溢出时)?鉴于time_t在我必须使用的系统上是 32 位签名的,有哪些替代方案?

大量的谷歌搜索没有发现任何实际用途。每个人似乎都认为到那时我们都将使用 64 位操作系统,但这显然不适用于嵌入式系统。

在我需要使用的系统上,__kernel_time_t定义为long. 这大概意味着 64 位时间没有内核设施。uClibc 的版本是 0.9.29。

我不敢相信我是唯一一个有这个问题的人,我不想重新发明轮子。

4

3 回答 3

10

没有灵丹妙药、技巧或聪明的解决方案。要么使用 64 位操作系统,要么time_t不使用time_t任何依赖它的操作系统设施(包括文件系统、计时器、半数网络等),或者计划在未来 20 年内更新软件。

在 32 位机器上至少有两个 64 位的类 unix 系统time_t:OpenBSD 和 NetBSD。OpenBSD 进行了几次会谈,解释了其背后的原因:http ://www.openbsd.org/papers/eurobsdcon_2013_time_t/index.html

于 2016-01-26T15:19:54.230 回答
8

如果时间戳低于某个值,时间转换例程将“简单地”使用 2038-01-19:03:14:07Z 作为 Unix Epoch 时间的基础。

即,如果您的系统在 2010 年 1 月 1 日开始生产,您可以假设没有未溢出的时间戳低于 1262300400(这是该日期的 unix 纪元时间)。

如果遇到较低的时间戳,则认为它已溢出并使用 2038-01-19:03:14:07Z 作为基准时间。比较也必须考虑在内。

不是一个干净的解决方案,但可以通过适度的努力。更好地切换到 64 位时间戳(这并不绝对需要 64 位系统,顺便说一句)。

于 2016-01-26T14:28:20.450 回答
4

我假设您的嵌入式系统的 ABI 定义long为 32 位。

time_t对要签名的类型没有要求。你能做到unsigned long并为自己和你的后代多买 68 年的安宁吗?改变这一点需要重新编译内核、C 库和所有使用的程序和库time_t......不是胆小的人!您不妨将其定义为long long,但这会改变许多结构布局并且更具挑战性。

于 2016-01-26T15:00:22.753 回答