web-dev-qa-db-ja.com

UNIX時間をdatetimeオブジェクトに変換し、再び元に戻します(逆の時間変換関数のペア)

私は、通常のUNIX時間(1970-01-01 00:00:00 UTCからの秒数)の間で前後に変換するdtutのペアの関数を記述しようとしています。 Python datetimeオブジェクト。

dtutが適切な逆である場合、このコードは同じタイムスタンプを2回出力します。

import time, datetime

# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.fromtimestamp(u)
def ut(d): return time.mktime(d.timetuple())

u = 1004260000
print u, "-->", ut(dt(u))

残念ながら、2番目のタイムスタンプは最初のタイムスタンプよりも3600秒(1時間)短いです。これは非常に特定のunixtimesでのみ起こると思います。たぶん、その時間に夏時間が省けます。しかし、dtutを書く方法はあるので、それらは互いに真の逆になりますか?

関連する質問: matplotlibのdate2numとnum2dateを完全に逆にする

26
dreeves

この動作が夏時間に関連していることは正しいです。これを回避する最も簡単な方法は、夏時間なしでタイムゾーンを使用することです。UTCはここで最も理にかなっています。

datetime.datetime.utcfromtimestamp() および calendar.timegm() UTC時間を処理し、正確な逆数です。

_import calendar, datetime

# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.utcfromtimestamp(u)
def ut(d): return calendar.timegm(d.timetuple())
_

なぜ datetime.datetime.fromtimestamp() が夏時間の問題を抱えているのかについては、ドキュメントから少し説明します。

time.time()によって返されるような、POSIXタイムスタンプに対応するローカルの日付と時刻を返します。オプションの引数tzがNoneまたは指定されていない場合、タイムスタンプはプラットフォームのローカルの日付と時刻に変換され、返されるdatetimeオブジェクトは単純です。

ここで重要な部分は、単純な_datetime.datetime_オブジェクトを取得することです。つまり、オブジェクトの一部としてタイムゾーン(または夏時間)情報がありません。これは、夏時間のロールバック中に落ちる時間を選択した場合、fromtimestamp()を使用すると、複数の異なるタイムスタンプが同じ_datetime.datetime_オブジェクトにマップできることを意味します。

_>>> datetime.datetime.fromtimestamp(1004260000) 
datetime.datetime(2001, 10, 28, 1, 6, 40)
>>> datetime.datetime.fromtimestamp(1004256400)
datetime.datetime(2001, 10, 28, 1, 6, 40)
_
39
Andrew Clark