27

通常の UNIX 時間 (1970-01-01 00:00:00 UTC からの秒数) と Python の datetime オブジェクトの間で相互に変換する関数dtとのペアを作成しようとしています。ut

dtとが適切な逆である場合ut、このコードは同じタイムスタンプを 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 時間) 短くなっています。これは非常に特定の unixtime でのみ発生すると思います。おそらく、夏時間がスキップされるその時間帯です。しかし、書く方法はありdtますutか?それで、それらは互いに真の逆になりますか?

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

4

1 に答える 1

41

この動作が夏時間に関連していることは間違いありません。これを回避する最も簡単な方法は、夏時間のないタイム ゾーンを使用することです。ここでは 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()docs から、夏時間に問題がある理由の背後にある少しの説明を次に示します。

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

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

>>> datetime.datetime.fromtimestamp(1004260000) 
datetime.datetime(2001, 10, 28, 1, 6, 40)
>>> datetime.datetime.fromtimestamp(1004256400)
datetime.datetime(2001, 10, 28, 1, 6, 40)
于 2012-11-06T23:18:24.040 に答える