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