2

私は次のコードを手に入れました

    timestamp = datetime.utcfromtimestamp(float(timestamp))
    now = datetime.utcnow()

    if now < timestamp:
        return False

時々、それは戻りますFalse。しかし、たまにしかありません。

printちょうど状態チェックで私にこれを与えます:

now 2013-02-28 18:02:57.015817
timestamp 2013-02-28 18:02:57.020000

したがって、タイムスタンプは数ミリ秒の間「バック・トゥ・ザ・フューチャー」を再生しているようです。

タイムスタンプは(datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()、前の呼び出しのから生成されます。

この結果は、最近のUbuntuのDjangoプロジェクトでpy.testによって実行された単体テストで取得されました。

私の現在の解決策は、すべてをタイムスタンプにし、ミリ秒を調整して比較することです。私がそうしても大丈夫です。なぜこれが起こるのか理解したいだけですか?

4

4 に答える 4

2

推測では、adatetimeは正確であり、マイクロ秒数を個別の整数として格納します。しかし、afloatはあいまいです。2進数として保存されるため、わずかに丸められる場合があります。

total_secondsただし、タイムスタンプへの変換に使用するべきではありません。代わりにこれを行ってください:

import calendar
timestamp = calendar.timegm(datetime.utcnow().timetuple())

これは、便利なことに、とにかく整数を返すだけです。

于 2013-02-28T18:18:38.303 に答える
0

あなたは-でキャストtimestampしていますfloat-この丸め操作は時々上向きに丸めることができるので、now < timestamp条件付きになりますか?

于 2013-02-28T18:19:05.820 に答える
0

編集:フロートから日付をキャストするときの丸めの問題について話している他の人々は、おそらく正しい答えを持っています。

問題は、コード内の変数名スコープを混乱させていることだと思います。それ以外の:

timestamp = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
timestamp = datetime.utcfromtimestamp(float(timestamp ))
now = datetime.utcnow()

次のようなものにリファクタリングしてみてください。

ts = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
timestamp = datetime.utcfromtimestamp(float(ts))
now = datetime.utcnow()

そして、何が起こるかを見てください。このようなさまざまな変換を実行する正当な理由は実際にはありませんtimestamp。この方法で何が起こっているのかを正確にデバッグする方が簡単です。

于 2013-02-28T18:21:45.257 に答える
0

主な理由はfloat -> str、質問に表示されていない変換(タイムスタンプから文字列)です。例:

from datetime import datetime
from itertools import count


def main():
    for i in count():
        timestamp = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
        s_timestamp = str(timestamp)
        dt_from_str = datetime.utcfromtimestamp(float(s_timestamp))
        now = datetime.utcnow()
        if now < dt_from_str:
            dt = datetime.utcfromtimestamp(timestamp)
            for o in [now, dt_from_str, dt, timestamp, s_timestamp, i]:
                print(repr(o))
            break

main()

出力:

datetime.datetime(2013, 3, 17, 15, 52, 38, 355006)
datetime.datetime(2013, 3, 17, 15, 52, 38, 360000)
datetime.datetime(2013, 3, 17, 15, 52, 38, 355003)
1363535558.355003
'1363535558.36'
688

dt( )は(datetime(2013, 3, 17, 15, 52, 38, 355003))よりも小さいはずであり、式( )で丸めが行われることに注意してください。nowdatetime(2013, 3, 17, 15, 52, 38, 355006)str(timestamp)'1363535558.36'

于 2013-03-17T15:54:17.917 に答える