6

仕様にアクセスできない古いデータ形式のDateTime構造があります。データの日時を示すフィールドがありますが、私が認識している形式ではありません。これは32ビット整数として格納されているように見え、1日ごとに20ずつ増加します。誰かがこのようなものに出くわしたことがありますか?

編集:

例:1088631936 DEC = 80 34 E3 40 00 00 00 00 HEX=2007年9月7日

編集:

まず、遅れてすみません。私は週末に何かをしたいと思っていましたが、できませんでした。

第二に、この日付形式は私が最初に思ったよりも奇妙です。日付が増加する速度で変化しないため、これはある種の指数法または対数法のように見えます。

第三に、これらの値を解釈するために私が持っている古いアプリは日付部分しか表示しないので、時間部分が何であるかわかりません。

データ例:(16進値はビッグエンディアン、日付は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 ..

編集:私はついにこれを理解しました、しかし私はすでに賞金のためのポイントをあきらめたので、誰かがそれを撃ちたいと思う場合に備えて私は解決策を延期します。

ところで、これには時間の要素はありません。純粋に日付を保存するためのものです。

4

5 に答える 5

7

整数ではなく、32ビットの浮動小数点数です。私はまだフォーマットを完全に理解していません、それはIEEEではありません。

編集:それを手に入れました。1ビットの符号、0x3ffのオフセットを持つ11ビットの指数、および左側に暗黙のビットを持つ20ビットの仮数。Cでは、正の数のみを想定しています。

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

これにより、0x40000000 = 2.0になるため、開始日は1899年12月30日である必要があります。

もう一度編集してください。あなたは私の答えを受け入れてくれて親切で、スピードについて心配しているようですので、これを少し洗練させたいと思いました。実数の小数部分は必要ないため、ビット演算のみを使用して整数に直接変換できます。今回の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
于 2009-03-25T05:33:53.330 に答える
3

値が2007年9月7日に対応していることを確認しますか?

1088631936は、Linux(et al)のゼロ日付からの秒数であるため質問します:1970年1月1日00:00:00から2004年6月30日21:45:36。

この通常のゼロの日付からの値は秒であると考えるのが妥当なようです。

編集:これが正解ではない可能性が非常に高いことを私は知っています。これは1つのアプローチ(有効なアプローチ)ですが、より多くの情報が必要だと思います(コメントを参照)。これを(もう一度)編集して、他の誰かがそれに答えたりアイデアを与えたりすることを期待して、質問を前面に出します。私:公平で、スポーティーで、共有の精神を持って:D

于 2009-03-21T06:03:51.437 に答える
1

vmarquez は近いと思います。

UNIX エポックタイムとしての日付 2009-3-21 および 2009-3-22 は次のとおりです。

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'

そして、ここにそれらは16進数です:

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

最初の 5 桁だけを取ると、成長率は 21 になります。

于 2009-03-21T19:01:13.283 に答える
1

いくつかのコンテキストが役立ちます。あなたのデータ ファイルが文字通りまたは少なくとも比喩的にこのファイルのように見える場合、vmarquez は大金持ちです。

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

その参照は、Available Bandwith Estimation ツール (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 時間のオフセットがあるようです。(おそらく、スタンフォード ローカルで、夏時間で実行されます。)

于 2009-03-22T16:40:06.063 に答える
0

プログラムが 8 桁のうち 2 桁をどのように使用するかを示しただけなので、残りの 6 桁は無視されると仮定する必要があります (プログラムは、他の桁を使用して必要なことを実行できるため)。

したがって、入力形式は 40mn0000 と言えます。ここで、m と n は 2 桁の 16 進数です。

次に、出力は次のようになります: 01/01/1900 + floor((2^(m+1)-2) + n*2^(m-3)) 日

説明:

  1. 各例で、n を 1 ずつ増やすと、日数が 2^(m-3) 増えることに注意してください。
  2. n が F から 0 になるたびに、m がインクリメントされることに注意してください。

これら 2 つのルールを使用して数字をいじると、上記の方程式が得られます。(出力に小数日が表示されないために追加されたフロアを除く)。

2 つの別々の 16 進数変数 m と n を 1 つの 2 桁の 16 進数 H に置き換えることで、これを書き直すことができると思います。

于 2009-03-25T04:59:47.250 に答える