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

cha*_*rit 7 unix-timestamp

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

引用Unix Time上的Wikipedia页面

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

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


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

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

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


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

tml*_*len 6

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

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

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


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

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

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


因此,对于传输协议,需要固定以下内容:

  • The unit of the time value (ms, us, ...), depending on required precision and range
  • If the time is a time point and not a duration, the Epoch (date and time of value 0)
  • Whether it is stored in an integer (unsigned or signed, if it is a duration that can be negative), or as a floating point
  • The endianess of the 64bit value
  • If floating point is used, the format of the floating point value (normally IEEE 754)

Because different platforms have different APIs to get the current time, probably it would always need some code to properly convert the time value, but this is trivial.

  • 使用浮点类型可能对*持续时间*而不是绝对*时间点*有用。但是对于64位,无论如何都最好使用整数。 (2认同)

JL2*_*210 4

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

我建议你使用clock_tandclock()时间函数。它有多种用途,包括测量程序中一点与另一点之间的时间和距离。只需确保将结果转换为 adouble并随后除以CLOCKS_PER_SEC将该时间转换为人类可读的格式。

所以,回答你的问题:

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