我应该如何精确地编码Unix时间?

时间:2019-05-14 09:54:28

标签: unix-timestamp

我之所以遇到这个问题,是因为我在多个平台上使用时间,似乎它们在系统中实现和/或处理unix时间的方式都彼此有些不同。这样的问题。

引用Wikipedia page on Unix Time

  

Unix没有将非整数Unix时间数直接表示为二进制分数的传统。取而代之的是,使用包含两个整数的复合数据类型来表示具有亚秒精度的时间,第一个是time_t(Unix时间的整数部分),第二个是时间数的分数部分(以百万分之一为单位) struct timeval)或十亿分之一(在struct timespec中)。这些结构提供了基于十进制的定点数据格式,该格式对某些应用程序很有用,而对于其他应用程序则很容易转换。

这似乎是Go(UnixNano)中的实现。但是,实际上,有许多使用毫秒(Java?)的语言/平台,并且某些平台使用Float(试图保持一定的精度),而其他平台则主要使用Int。


因此,如果我要实现一种传输格式,而我只能使用64位来存储时间值,而没有更多的话,我的问题有两个:

  • 我应该将其编码为整数还是浮点值?还有
  • 我应该使用秒,毫秒还是纳秒精度?

主要目标是尝试在尽可能多的语言和平台上尽可能地准确(当然,在每个平台上都不必诉诸自定义代码)。


p.s。我知道这有点主观,但我相信仍然有可能做出一个很好的,客观的答案。如果不是这种情况,请随时关闭。

2 个答案:

答案 0 :(得分:4)

这取决于时间值的要求精度及其最大范围。

当以无符号的64位整数存储纳秒时,范围约为584年(2 ^ 64 ns),因此精确度和足够长,足以用于任何实际应用。

使用浮点格式的优点是可以存储非常小的值和非常大的值,对于较小的值,绝对精度更高。但是使用64位,无论如何这可能不是问题。


如果时间值是绝对时间点而不是持续时间,则转换格式还需要定义值0代表的日期/时间。 (即时代)

例如,可以使用gettimeofday()在类似UNIX的系统上获取当前时间,它返回一个带有秒和微秒值的结构。然后可以将其转换为单个64位整数,以毫秒为单位给出一个值。 UNIX时间的纪元是1970年1月1日UT。 (clock()函数不是实时测量,而是处理器活动的持续时间。)

在另一个平台(例如,带有GetSystemTime()的Windows)上生成具有相同传输格式的时间值时,需要将其转换为相同的单位和纪元。


因此,对于传输协议,需要解决以下问题:

  • 时间值的单位(ms,us,...),取决于所需的精度和范围
  • 如果时间是一个时间点而不是一个持续时间,则为纪元(日期和时间值为0)
  • 是将其存储为整数(无符号或有符号,如果持续时间可以为负)还是浮点数
  • 64位值的终结性
  • 如果使用浮点,则为浮点值的格式(通常为IEEE 754)

由于不同的平台使用不同的API来获取当前时间,可能总需要一些代码来正确转换时间值,但这很简单。

答案 1 :(得分:3)

为获得最大的便携性和准确性,您可能应该使用POSIX指定的类型。这样,该代码将可以在所有Unix和符合POSIX的其他操作系统上移植。

我建议您使用clock_tclock()函数来节省时间。它具有多种用途,包括测量程序中一个点与另一点之间的时间和距离。只需确保将结果转换为double,然后除以CLOCKS_PER_SEC,即可将该时间转换为易于理解的格式。

因此,回答您的问题:

  1. 同时使用整数和浮点值
  2. 不确定精度(两次调用之间的时钟周期数),但对于所有非关键性应用程序和一些更重要的应用程序而言,精度足够