dt = datetime(2013,9,1,11)`があり、このdatetimeオブジェクトのUnixタイムスタンプを取得したいと考えています。
(dt - datetime(1970,1,1)).total_seconds()を実行すると、タイムスタンプ
1378033200` が得られました。
これを datetime.fromtimestamp
で変換すると、datetime.datetime(2013, 9, 1, 6, 0)
となります。
時間が一致しません。何か問題があったのでしょうか?
ここで見落としていたのがタイムゾーンです。
おそらく、あなたはUTCから5時間ずれているので、現地の2013-09-01T11:00:00と、2013-09-01T06:00:00Zは同じ時間です。
datetime`](http://docs.python.org/3.3/library/datetime.html)のドキュメントの一番上の部分を読む必要があります。そこにはタイムゾーンや、"naive"と"aware"オブジェクトについての説明があります。
もし元々のナイーブなデータタイムがUTCだった場合、それを回復する方法は、fromtimestamp
の代わりにutcfromtimestamp
を使うことです。
一方、元々の素のデータタイムがローカルであった場合、そもそもそこからUTCタイムスタンプを引くべきではなく、代わりに datetime.fromtimestamp(0)
を使用します。
代わりに datetime.fromtimestamp(0)
を使用してください。また、認識可能な datetime オブジェクトがあった場合は、ローカルな(認識可能な)エポックを両サイドで使用するか、明示的に UTC との間で変換する必要があります。
もしあなたがPython 3.3以降を持っているか、アップグレードできるのであれば、自分でやり方を考えようとするのではなく、単にtimestamp
メソッドを使うことで、これらの問題をすべて回避できます。また、そうでない場合でも、ソースコードを借りることを検討してみてはいかがでしょうか。
(そして、もしあなたがPython 3.4を待つことができるなら、PEP 341が最終リリースになりそうです。つまり、J.F. Sebastianと私がコメントで話していたすべてのことがstdlibだけで可能になり、UnixでもWindowsでも同じように動作するということです)。
この式ではなく、dt
からPOSIXのタイムスタンプを作成します。
(dt - datetime(1970,1,1)).total_seconds()
これを使います。
int(dt.strftime("%s"))
あなたの例では、2番目の方法で正しい答えが得られます。
EDIT: いくつかのフォローアップ...いくつかのコメント(下記参照)の後、私は strftime
の中の %s
に対するサポートやドキュメントがないことに興味を持ちました。これは私が見つけたものです。
datetimeと
timeの[Pythonソース](https://github.com/python/cpython/blob/master/Modules/timemodule.c)では、文字列
STRFTIME_FORMAT_CODES`が教えてくれています。
"Other codes may be available on your platform.
See documentation for the C library strftime function."
これで、(Mac OS XなどのBSDシステムで)strftimeをman
すると、%s
がサポートされていることがわかります。
"%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3))."
とにかく、これが %s
が動作するシステムの理由です。 しかし、OP'の問題に対して、(タイムゾーンを考慮した)より良い解決策があります。 こちらの @abarnert'さんの回答をご覧ください。
unixのタイムスタンプに変換するとき、pythonは基本的にUTCを前提としていますが、逆に変換するときはローカルのタイムゾーンに変換された日付が表示されます。
こちらの質問と回答をご覧ください。 https://stackoverflow.com/questions/18812638/get-timezone-used-by-datetime-datetime-fromtimestamp