Pythonのdatetimeで日付や時間と文字列を変換(strftime, strptime)
Pythonの標準ライブラリdatetimeで、日時(日付や時間・時刻)を処理できる。日時と文字列を相互に変換するメソッドstrftime()とstrptime()で、様々なフォーマットの日付や時間を操作できる。
引き算や足し算も可能で、例えば、10日前の日付や50分後の時刻などを計算できる。
datetimeモジュールでは以下のクラスが定義されている。モジュール名と日時を扱うクラス名が同じdatetimeなので混同しないように要注意。
datetime.datetime: 日時(日付と時刻)datetime.date: 日付datetime.time: 時刻datetime.timedelta: 時間差・経過時間
ここでは、それぞれのクラスについて説明したあとで、日時と文字列を相互に変換するメソッドstrftime()とstrptime()について説明する。
ISO 8601形式の文字列やUNIX時間(エポック秒)との相互変換やタイムゾーンに関する処理についての詳細は以下の記事を参照。
- 関連記事: PythonでISO 8601形式の文字列と日時datetimeを相互変換
- 関連記事: PythonでUNIX時間(エポック秒)と日時datetimeを相互変換
- 関連記事: Python, datetime, pytzでタイムゾーンを設定・取得・変換・削除
また、プレーンテキストやHTML形式のカレンダーを生成するcalendarモジュールも標準ライブラリに含まれている。
datetimeオブジェクト(日時を扱う)
datetimeオブジェクトは日付(年、月、日)と時刻(時、分、秒、マイクロ秒)の情報を持つ。それらの情報に、属性year, month, day, hour, minute, second, microsecondでアクセスできる。
datetime.now(): 今日の日付、現在時刻
datetime.now()で現在日時(今日の日付と現在時刻)のdatetimeオブジェクトが得られる。
yearなどの属性は整数intとして取得できる。以降で説明するdate, timeオブジェクトの属性も同様。
import datetime
dt_now = datetime.datetime.now()
print(dt_now)
# 2023-04-08 23:08:13.873520
print(type(dt_now))
# <class 'datetime.datetime'>
print(dt_now.year)
# 2023
print(type(dt_now.year))
# <class 'int'>
datetimeオブジェクトのコンストラクタ
datetimeオブジェクトのコンストラクタは以下の通り。任意の日付・時刻のdatetimeオブジェクトを生成できる。
datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
年year、月month、日dayは必須でそのほかは省略可能。省略した場合は0になる。
print(datetime.datetime(2023, 4, 1, 20, 15, 30, 2000))
# 2023-04-01 20:15:30.002000
print(datetime.datetime(2023, 4, 1))
# 2023-04-01 00:00:00
datetimeオブジェクトからdate, timeオブジェクトへの変換
datetimeオブジェクトのdate(), time()メソッドでdate, timeオブジェクトに変換できる。
dt = datetime.datetime(2023, 4, 1, 20, 15, 30, 2000)
d = dt.date()
print(d)
# 2023-04-01
print(type(d))
# <class 'datetime.date'>
t = dt.time()
print(t)
# 20:15:30.002000
print(type(t))
# <class 'datetime.time'>
date, timeオブジェクトからdatetimeオブジェクトを生成
datetimeクラスのクラスメソッドcombine()で、既存のdate, timeオブジェクトからdatetimeオブジェクトを生成できる。
第一引数にdateオブジェクト、第二引数にtimeオブジェクトを指定する。
print(datetime.datetime.combine(d, t))
# 2023-04-01 20:15:30.002000
dateオブジェクト(日付を扱う)
dateオブジェクトは日付(年、月、日)の情報を持つ。それらの情報に、属性year, month, dayでアクセスできる。
date.today(): 今日の日付
date.today()で現在の日付(今日の日付)のdateオブジェクトが得られる。
d_today = datetime.date.today()
print(d_today)
# 2023-04-08
print(type(d_today))
# <class 'datetime.date'>
print(d_today.month)
# 4
dateオブジェクトのコンストラクタ
dateオブジェクトのコンストラクタは以下の通り。任意の日付のdateオブジェクトを生成できる。
date(year, month, day)
すべて必須で、省略はできない。
print(datetime.date(2023, 4, 1))
# 2023-04-01
timeオブジェクト(時刻を扱う)
timeオブジェクトは時刻(時、分、秒、マイクロ秒)の情報を持つ。それらの情報に、属性hour, minute, second, microsecondでアクセスできる。
現在時刻のtimeオブジェクト
現在時刻のtimeオブジェクトを生成するメソッドはPython 3.11時点では提供されていない。datetime.now()で現在日時のdatetimeオブジェクトを生成して、time()メソッドでtimeオブジェクトに変換すればよい。
t_now = datetime.datetime.now().time()
print(t_now)
# 23:08:13.919031
print(type(t_now))
# <class 'datetime.time'>
print(t_now.microsecond)
# 919031
timeオブジェクトのコンストラクタ
timeオブジェクトのコンストラクタは以下の通り。任意の時刻のtimeオブジェクトを生成できる。
time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
すべて省略可能で、省略した場合は0となる。
print(datetime.time(20, 15, 30, 2000))
# 20:15:30.002000
print(datetime.time())
# 00:00:00
timedeltaオブジェクト(時間を扱う)
timedeltaオブジェクトは二つの日時の時間差、経過時間を表す。日数、秒数、マイクロ秒数の情報を持ち、属性days, seconds, microsecondsでアクセスできる。
また、total_seconds()メソッドでトータルの秒数(マイクロ秒を含む)を浮動小数点数floatで取得することも可能。
datetime, dateオブジェクトの引き算でtimedeltaオブジェクトを生成
datetimeオブジェクト同士を引き算-すると、timedeltaオブジェクトが得られる。
dt1 = datetime.datetime(2023, 4, 1, 20, 15, 30, 2000)
dt2 = datetime.datetime(2023, 7, 1, 10, 45, 15, 100)
td = dt2 - dt1
print(td)
# 90 days, 14:29:44.998100
print(type(td))
# <class 'datetime.timedelta'>
print(td.days)
# 90
print(td.seconds)
# 52184
print(td.microseconds)
# 998100
print(td.total_seconds())
# 7828184.9981
dateオブジェクト同士の引き算でも同様にtimedeltaオブジェクトが得られる。
timedeltaオブジェクトのコンストラクタ
timedeltaオブジェクトのコンストラクタは以下の通り。
timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
すべて省略可能で、省略した場合は0となる。
なお、timedeltaオブジェクトが保持しているのは、日数days, 秒数seconds, マイクロ秒数microsecondsの情報のみで、例えばweeks=1はdays=7と等しい。
td_1w = datetime.timedelta(weeks=1)
print(td_1w)
# 7 days, 0:00:00
print(td_1w.days)
# 7
秒を分や時間に変換したい場合は以下の記事を参照。
- 関連記事: Pythonで秒数と分・時間・日数を相互に変換
timedeltaオブジェクトを使った引き算、足し算
timedeltaオブジェクトはdatetimeオブジェクトやdateオブジェクトとの引き算や足し算が可能。例えば、1週間前とか10日後の日付や50分後の時刻などを簡単に計算できる。
dt = datetime.datetime(2023, 4, 1, 20, 15, 30, 2000)
print(dt)
# 2023-04-01 20:15:30.002000
print(dt - datetime.timedelta(weeks=1))
# 2023-03-25 20:15:30.002000
print(dt + datetime.timedelta(days=10))
# 2023-04-11 20:15:30.002000
print(dt + datetime.timedelta(minutes=50))
# 2023-04-01 21:05:30.002000
特定の日付までの日数を算出するのにも使える。
d_target = datetime.date(2023, 5, 1)
td = d_target - dt.date()
print(td)
# 30 days, 0:00:00
print(td.days)
# 30
時差(タイムゾーン)を扱う場合の処理についての詳細は以下の記事を参照。
strftime(): 日付・時間から文字列への変換
datetime, date, timeオブジェクトのstrftime()メソッドで、日時(日付、時間)を任意のフォーマットの文字列に変換できる。
書式コード
使用できる書式コードは公式ドキュメントを参照。
主な書式コードを挙げておく。
%d: 0埋めした10進数で表記した月中の日にち%m: 0埋めした10進数で表記した月%y: 0埋めした10進数で表記した西暦の下2桁%Y: 0埋めした10進数で表記した西暦4桁%H: 0埋めした10進数で表記した時 (24時間表記)%I: 0埋めした10進数で表記した時 (12時間表記)%M: 0埋めした10進数で表記した分%S: 0埋めした10進数で表記した秒%f: 0埋めした10進数で表記したマイクロ秒(6桁)%A: ロケールの曜日名%a: ロケールの曜日名(短縮形)%B: ロケールの月名%b: ロケールの月名(短縮形)%j: 0埋めした10進数で表記した年中の日にち(正月が'001')%U: 0埋めした10進数で表記した年中の週番号 (週の始まりは日曜日)%W: 0埋めした10進数で表記した年中の週番号 (週の始まりは月曜日)
曜日名や月名の%A, %a, %B, %bはロケールによって取得できる文字列が異なる。詳細は以下の記事を参照。
これらの書式コードはformat()やf文字列の書式化指定文字列でも使用できる。
また、ISO 8601形式の文字列については専用のメソッドが用意されている。
サンプルコード
以下、いくつか例を示す。
dt = datetime.datetime(2023, 4, 1, 20, 15, 30, 2000)
print(dt.strftime('%Y/%m/%d %H:%M:%S.%f'))
# 2023/04/01 20:15:30.002000
print(dt.strftime('%A, %B %d, %Y'))
# Saturday, April 01, 2023
strftime()メソッドはdate, timeオブジェクトからも使える。dateで時刻、timeで日付に関する書式コードを使ってもエラーにはならず、初期値(0や1)とみなされる。
d = dt.date()
print(d.strftime('%Y/%m/%d %H:%M:%S.%f'))
# 2023/04/01 00:00:00.000000
t = dt.time()
print(t.strftime('%Y/%m/%d %H:%M:%S.%f'))
# 1900/01/01 20:15:30.002000
timedeltaオブジェクトと組み合わせて、例えば、任意のフォーマットで隔週の日付のリストを作るみたいなことも簡単にできる。
- 関連記事: Pythonリスト内包表記の使い方
- 関連記事: Pythonで文字列を連結・結合(+演算子、joinなど)
d = datetime.date(2023, 4, 1)
td = datetime.timedelta(weeks=2)
n = 4
f = '%Y/%m/%d'
l = [(d + i * td).strftime(f) for i in range(n)]
print(l)
# ['2023/04/01', '2023/04/15', '2023/04/29', '2023/05/13']
print('\n'.join(l))
# 2023/04/01
# 2023/04/15
# 2023/04/29
# 2023/05/13
strptime(): 文字列から日付・時間への変換
datetimeクラスのクラスメソッドであるstrptime()で、日付や時刻を表す文字列からdatetimeオブジェクトを生成できる。
こちらもISO 8601形式の文字列については専用のメソッドが用意されている(Python3.7以降)。以下の記事を参照。
サンプルコード
strptime()の第一引数に対象の文字列、第二引数に書式化文字列を指定する。
s = '2023/4/1 20:30'
s_format = '%Y/%m/%d %H:%M'
dt = datetime.datetime.strptime(s, s_format)
print(dt)
# 2023-04-01 20:30:00
print(type(dt))
# <class 'datetime.datetime'>
取得したdatetimeオブジェクトでstrftime()メソッドを使うことで、元の文字列と異なるフォーマットの文字列に変換できる。
print(dt.strftime('%Y%m%d_%H%M'))
# 20230401_2030
datetimeオブジェクトに変換してしまえばtimedeltaオブジェクトと演算できるので、例えば同じフォーマットで10日前の日付の文字列を生成したりすることも可能。
s = '2023/4/1'
s_format = '%Y/%m/%d'
td_10d = datetime.timedelta(days=10)
dt = datetime.datetime.strptime(s, s_format) - td_10d
print(dt.strftime(s_format))
# 2023/03/22