pythonの日時の操作

pythonの日時の操作

なんとなくやってきてしまったので備忘録として残しておきたいと思います。ちゃんと把握したい方は参考のサイトnote.nkmk.meをご覧くださいませ。

参考:
  ・Pythonで現在時刻・日付・日時を取得
  ・PythonでISO 8601形式の文字列と日時datetimeを相互変換
  ・Pythonで日付操作を完全マスター!!
  ・【Django】naive timeをaware timeに変換する方法

文字列とdatetimeオブジェクト

datetimeオブジェクトを文字列に変換する方法と文字列をdatetimeオブジェクトに変換する方法です。


import datetime

# datetimeオブジェクトを生成
date = datetime.datetime(2020, 10, 10, 10, 10, 10)
print(date) # 2020-10-10 10:10:10
print(type(date)) # <class 'datetime.datetime'>

# 文字列に変換
date = date.strftime("%Y-%m-%d %H:%M:%S")
print(date) # 2020-10-10 10:10:10
print(type(date)) # <class 'str'>

# datetimeオブジェクトに変換
date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
print(date) # 2020-10-10 10:10:10
print(type(date)) # <class 'datetime.datetime'>

日時の加算

日時を加算する方法です。


# datetimeオブジェクトを生成
date = datetime.datetime(2020, 10, 10, 10, 10, 10)
print(date) # 2020-10-10 10:10:10
print(type(date)) # <class 'datetime.datetime'>

# 1週間加算
d = date + datetime.timedelta(weeks=1)
print(d) # 2020-10-17 10:10:10

# 1日加算
d = date + datetime.timedelta(days=1)
print(d) # 2020-10-11 10:10:10

# 10時間加算
d = date + datetime.timedelta(hours=10)
print(d) # 2020-10-10 20:10:10

# 10分加算
d = date + datetime.timedelta(minutes=10)
print(d) # 2020-10-10 10:20:10

# 10秒加算
d = date + datetime.timedelta(seconds=10)
print(d) # 2020-10-10 10:10:20

日付と時間に分ける

日付だけ欲しい時や時間だけ欲しい時があります。


# datetimeオブジェクトを生成
date = datetime.datetime(2020, 10, 10, 10, 10, 10)
print(date) # 2020-10-10 10:10:10
print(type(date)) # <class 'datetime.datetime'>

# 文字列に変換
date = date.strftime("%Y-%m-%d %H:%M:%S")
print(date) # 2020-10-10 10:10:10
print(type(date)) # <class 'str'>

date, time = date.split()
print(date) # 2020-10-10
print(time) # 10:10:10

isoformatとdatetimeオブジェクト

ISOフォーマットとは「日付と時刻の表記に関するISOの国際規格」でpythonでは文字列で扱われます。表記には下記の通りのルールがあるみたいです。
フリー百科事典『ウィキペディア(Wikipedia)』参考


日付と時刻をT記号で区切り、時分秒の表記はコロン (:) で区切る。
末尾にUTCであればZ記号、他のタイムゾーンならばプラス記号 (+) 
あるいはマイナス記号 (-) で区切って続ける。

isoformatとdatetimeオブジェクトを相互に変換してみます。


# datetimeオブジェクトを生成
date = datetime.datetime(2020, 10, 10, 10, 10, 10)
print(date) # 2020-10-10 10:10:10
print(type(date)) # <class 'datetime.datetime'>

# isoformatに変換
date = date.isoformat()
print(date) # 2020-10-10T10:10:10
print(type(date)) # <class 'str'>

# datetimeオブジェクトに変換
date = datetime.datetime.fromisoformat(date)
print(date) # 2020-10-10 10:10:10
print(type(date)) # <class 'datetime.datetime'>

UTC(協定世界時)を表す場合は末尾にZを付けるが、fromisoformat()はこれに対応しておらず、末尾にZが付いた文字列はエラーになる。「Z」は「+00:00」と同意なので置換することで解決できるとの事です。


# UTC指定でisoformatの日時を生成
date = "2020-10-10T10:10:10Z"

# datetimeオブジェクトに変換 -> エラー
date = datetime.datetime.fromisoformat(date)
# ValueError: Invalid isoformat string: '2020-10-10T10:10:10Z'

# +00:00に置換
date = date.replace('Z', '+00:00')
print(date) # 2020-10-10T10:10:10+00:00

# datetimeオブジェクトに変換
date = datetime.datetime.fromisoformat(date)
print(date) # 2020-10-10 10:10:10+00:00

タイムゾーン

タイムゾーンの概念には二種類あるとの事です。一つは、naive time(タイムゾーンを意識しない時間)でありもう一つは、aware time(タイムゾーンを意識した時間)です。違いをそれぞれ確認してみます。


# 現在日時を取得
dt_now_naive = datetime.datetime.now()
print(dt_now_naive) # 2021-01-26 23:29:38.429367

# UTCの現在日時を取得
dt_now_utc_aware = datetime.datetime.now(datetime.timezone.utc)
print(dt_now_utc_aware) # 2021-01-26 14:29:38.430367+00:00

# JSTの現在日時を取得
dt_now_jst_aware = datetime.datetime.now(
    datetime.timezone(datetime.timedelta(hours=9))
)
print(dt_now_jst_aware) # 2021-01-26 23:29:38.430367+09:00