Python の datetime オブジェクトと Unix 時間の相互変換方法のまとめ

Python の datetime オブジェクトと Unix 時間 (Unix time / Epoch time) を相互変換する方法についてまとめます. Python の datetime オブジェクトにはタイムゾーン情報が付いているもの (aware) と付いていないもの (naive) があるので注意が必要です.

Unix 時間

Unix 時間 (Unix time) は UTC での 1970/1/1 00:00:00 からの経過秒数で表されます. 多くのシステムでは閏秒の存在を考慮しない実装となっているようで, この場合 Unix time と UTC, JST の対応は以下のようになります.

Unix time UTC JST (UTC+9)
0 1970/1/1 00:00:00 1970/1/1 09:00:00
1429000000 2015/4/14 08:26:40 2015/4/14 17:26:40

“naive” と “aware”

Python の datetime オブジェクトには “naive” と “aware” の2種類のオブジェクトがあります. aware オブジェクトはタイムゾーン情報を持つオブジェクトで tzinfo にタイムゾーンの属性を持ちます. これに対して, naive オブジェクトはタイムゾーン情報を持たないオブジェクトです.

これについての詳細は Python の公式ドキュメントも参照してください.

ローカルタイムの naive オブジェクト

import datetime
import time


# ローカルタイムの naive オブジェクト
now = datetime.datetime.now()
print(now)

# ローカルタイムの naive オブジェクト -> Unix time
unix = int(time.mktime(now.timetuple()))
print(unix)

# Python 3.3 以降のみでは time モジュールを使わずに書くことが出来ます
# ローカルタイムの naive オブジェクト -> Unix time
unix = int(now.timestamp())
print(unix)

# Unix time -> ローカルタイムの naive オブジェクト
now = datetime.datetime.fromtimestamp(unix)
print(now)

UTC の naive オブジェクト

import calendar
import datetime


# UTC の naive オブジェクト
now = datetime.datetime.utcnow()
print(now)

# UTC の naive オブジェクト -> Unix time
unix = calendar.timegm(now.utctimetuple())
print(unix)

# Python 3.3 以降でも, UTC の naive なオブジェクトに対して,
# now.timestamp() を使うことはできません

# Unix time -> UTC の naive オブジェクト
now = datetime.datetime.utcfromtimestamp(unix)
print(now)

aware オブジェクト

aware オブジェクトの場合は, タイムゾーン情報を用いて一旦 UTC に変換して Unix time を求め, Unix time から datetime オブジェクトに戻す際に再びタイムゾーン情報を付加するような実装になります.

ここではタイムゾーン情報を扱うために pytz を利用しています.

import calendar
import datetime

import pytz


# UTC の aware オブジェクト
# Python 3.2 以降では tz = datetime.timezone.utc も可
tz = pytz.utc
now = datetime.datetime.now(tz)
print(now)

# UTC の aware オブジェクト -> Unix time
unix = calendar.timegm(now.utctimetuple())
print(unix)

# Python 3.3 以降では calendar モジュールを使わずに書けます
# UTC の aware オブジェクト -> Unix time
unix = int(now.timestamp())  # calendar.timegm と異なり float の値が返される
print(unix)

# Unix time -> UTC の aware オブジェクト
now = datetime.datetime.fromtimestamp(unix, tz=tz)
print(now)


# PST の aware オブジェクト
tz = pytz.timezone("US/Pacific")
now = datetime.datetime.now(tz)
print(now)

# PST の aware オブジェクト -> Unix time
unix = calendar.timegm(now.utctimetuple())
print(unix)

# Python 3.3 以降では calendar を使わずに書けます
# PST の aware オブジェクト -> Unix time
unix = int(now.timestamp())  # calendar.timegm と異なり float の値が返される
print(unix)

# Unix time -> PST の aware オブジェクト
now = datetime.datetime.fromtimestamp(unix, tz=tz)
print(now)

まとめ

Python では datetime オブジェクトが “naive” か “aware” かを意識することが重要になります. 詳細な部分については以下のリンクも参照してください.

変更履歴

  • 2017/1/24 Python 3.3 以降での datetime オブジェクトから unix time への変換について追記

参考