这是什么日期时间格式?

时间:2009-03-20 21:20:23

标签: datetime format

我有一个旧数据格式的DateTime结构,我无法访问任何规范。有一个字段指示数据的日期时间,但它不是我识别的任何格式。它似乎存储为32位整数,每天递增20。有没有人遇到这样的事情?

编辑:

示例:1088631936 DEC = 80 34 E3 40 00 00 00 00 HEX = 09/07/2007

编辑:

首先,抱歉延迟。我原本希望在周末做些什么,但是无法做到。

其次,这种日期格式比我最初的想法更怪异。它似乎是某种指数或对数方法,因为日期不会以递增的速度变化。

第三,我解释这些值的已解散的应用程序只显示日期部分,所以我不知道时间部分是什么。

示例数据: (十六进制值为big-endian,日期为mm / dd / yyyy)

0x40000000 = 01/01/1900
0x40010000 = 01/01/1900
0x40020000 = 01/01/1900
0x40030000 = 01/01/1900
0x40040000 = 01/01/1900
0x40050000 = 01/01/1900
0x40060000 = 01/01/1900
0x40070000 = 01/01/1900
0x40080000 = 01/02/1900
0x40090000 = 01/02/1900
0x400A0000 = 01/02/1900
0x400B0000 = 01/02/1900
0x400C0000 = 01/02/1900
0x400D0000 = 01/02/1900
0x400E0000 = 01/02/1900
0x400F0000 = 01/02/1900
0x40100000 = 01/03/1900
0x40110000 = 01/03/1900
0x40120000 = 01/03/1900
0x40130000 = 01/03/1900
0x40140000 = 01/04/1900
0x40150000 = 01/04/1900
0x40160000 = 01/04/1900
0x40170000 = 01/04/1900
0x40180000 = 01/05/1900
0x40190000 = 01/05/1900
0x401A0000 = 01/05/1900
0x401B0000 = 01/05/1900
0x401C0000 = 01/06/1900
0x401D0000 = 01/06/1900
0x401E0000 = 01/06/1900
0x401F0000 = 01/06/1900
0x40200000 = 01/07/1900
0x40210000 = 01/07/1900
0x40220000 = 01/08/1900
0x40230000 = 01/08/1900
....
0x40800000 = 05/26/1901
0x40810000 = 06/27/1901
0x40820000 = 07/29/1901
....
0x40D00000 = 11/08/1944
0x40D10000 = 08/29/1947

编辑:我终于明白了这一点,但是因为我已经放弃了赏金的积分,所以我会推迟解决方案以防万一有人想要试一试。

顺便说一下,没有时间组件,它纯粹是为了存储日期。

5 个答案:

答案 0 :(得分:7)

它不是整数,它是32位浮点数。我还没有完全确定格式,它不是IEEE。

编辑:得到它。 1位符号,11位指数,偏移量为0x3ff,20位尾数,左侧为隐含位。在C中,仅假设正数:

double offset = pow(2, (i >> 20) - 0x3ff) * (((i & 0xfffff) + 0x100000) / (double) 0x100000);

这会产生0x40000000 = 2.0,因此开始日期必须是12/30/1899。

再次编辑:因为你很善意接受我的答案,而你似乎对速度感到担心,我想我会稍微改进一下。您不需要实数的小数部分,因此我们可以仅使用按位运算直接转换为整数。在这次Python中,完成测试结果。我已经包含了一些中间值以提高可读性。除了没有负数的限制之外,当指数超过19时,这个版本可能会有问题,但这应该让你在3335年之前保持良好状态。

>>> def IntFromReal32(i):
        exponent = (i >> 20) - 0x3ff
        mantissa = (i & 0xfffff) + 0x100000
        return mantissa >> (20 - exponent)

>>> testdata = range(0x40000000,0x40240000,0x10000) + range(0x40800000,0x40830000,0x10000) + [1088631936]
>>> from datetime import date,timedelta
>>> for i in testdata:
        print "0x%08x" % i, date(1899,12,30) + timedelta(IntFromReal32(i))


0x40000000 1900-01-01
0x40010000 1900-01-01
0x40020000 1900-01-01
0x40030000 1900-01-01
0x40040000 1900-01-01
0x40050000 1900-01-01
0x40060000 1900-01-01
0x40070000 1900-01-01
0x40080000 1900-01-02
0x40090000 1900-01-02
0x400a0000 1900-01-02
0x400b0000 1900-01-02
0x400c0000 1900-01-02
0x400d0000 1900-01-02
0x400e0000 1900-01-02
0x400f0000 1900-01-02
0x40100000 1900-01-03
0x40110000 1900-01-03
0x40120000 1900-01-03
0x40130000 1900-01-03
0x40140000 1900-01-04
0x40150000 1900-01-04
0x40160000 1900-01-04
0x40170000 1900-01-04
0x40180000 1900-01-05
0x40190000 1900-01-05
0x401a0000 1900-01-05
0x401b0000 1900-01-05
0x401c0000 1900-01-06
0x401d0000 1900-01-06
0x401e0000 1900-01-06
0x401f0000 1900-01-06
0x40200000 1900-01-07
0x40210000 1900-01-07
0x40220000 1900-01-08
0x40230000 1900-01-08
0x40800000 1901-05-26
0x40810000 1901-06-27
0x40820000 1901-07-29
0x40e33480 2007-09-07

答案 1 :(得分:3)

您确定这些值对应于09/07/2007吗?

我问,因为1088631936是自Linux(等)零日期以来的秒数:01/01/1970 00:00:00至06/30/2004 21:45:36。

似乎我觉得这个值通常是零日期以来的秒数。

编辑:我知道这很可能不是正确的答案。这只是一种方法(有效方法),但我认为需要更多信息(参见评论)。编辑这个(再次)将问题放在前面,希望其他人回答它或提出想法。我:公平,体育和分享精神:D

答案 2 :(得分:1)

我会说vmarquez很接近。

以下是2009-3-21和2009-3-22的日期,作为unix epochtime:

In [8]: time.strftime("%s", (2009, 3, 21, 1, 1, 0, 0,0,0))
Out[8]: '1237590060'

In [9]: time.strftime("%s", (2009, 3, 22, 1, 1, 0, 0,0,0))
Out[9]: '1237676460'

这里他们是十六进制的:

In [10]: print("%0x %0x" % (1237590060, 1237676460))
49c4202c 49c571ac

如果你只取前5位数,那么增长是21.哪种方式符合你的格式,是吗?

答案 3 :(得分:1)

某些背景会很有用。如果您的数据文件看起来像字面上或者至少是比喻性的,就像这个文件一样,vmarquez就是钱。

http://www.slac.stanford.edu/comp/net/bandwidth-tests/eventanalysis/all_100days_sep04/node1.niit.pk

该引用是由可用带宽估计工具(ABwE)生成的数据 - 奇怪的项目是它实际上包含该1088631936值以及上下文。那个例子


 date     time       abw     xtr   dbcap   avabw   avxtr  avdbcap      rtt    timestamp
06/30/04 14:43:48  1.000   0.000   1.100   1.042   0.003    1.095  384.387   1088631828
06/30/04 14:45:36  1.100   0.000   1.100   1.051   0.003    1.096  376.408   1088631936
06/30/04 14:47:23  1.000   0.000   1.100   1.043   0.003    1.097  375.196   1088632043
似乎与建议的21:45:36时间值有7个小时的偏差。 (可能是斯坦福本地,在夏令时上运行。)

答案 4 :(得分:0)

好吧,你只是向我们展示了你的程序如何使用8位数中的2位,所以我们必须假设其他6位被忽略(因为你的程序可以用其他数字做任何想做的事)。

所以,我们可以说输入格式是: 40mn0000 其中m和n是两个十六进制数字。

然后,输出是: 01/01/1900 + floor((2 ^(m + 1)-2)+ n * 2 ^(m-3))天

说明:

  1. 在每个示例中,请注意,将n递增1会使天数增加2 ^(m-3)。
  2. 请注意,每当n从F变为0时,m都会递增。
  3. 使用这两个规则,并使用数字,你可以得到上面的等式。 (除了因为输出不显示小数天而添加的地板除外)。

    我想你可以通过用一个2位十六进制数H替换两个单独的十六进制变量m和n来重写这个。但是,我认为这会使方程变得更加丑陋。

相关问题