Pythonのdatetimeで日付や時間と文字列を変換(strftime, strptime)
Pythonの標準ライブラリdatetimeを使って、日時(日付や時間・時刻)の処理ができる。日時と文字列を相互に変換するメソッドstrftime()
とstrptime()
で、様々なフォーマットの日付や時間を操作することが可能。
また、引き算や足し算などの演算も可能で、例えば、10日前とか3週間後の日付や50分後の時刻などを簡単に計算して取得できる。
ここでは、datetimeモジュールで利用できる、
datetime.datetime
: 日時(日付と時刻)datetime.date
: 日付datetime.time
: 時刻datetime.timedelta
: 時間差・経過時間
のクラスのオブジェクトについて説明したあとで、日時と文字列を相互に変換するメソッドstrftime()
とstrptime()
について説明する。
datetime
オブジェクトdatetime.now()
: 今日の日付、現在時刻datetime
オブジェクトのコンストラクタdatetime
オブジェクトからdate
オブジェクトへの変換
date
オブジェクトdate.today()
: 今日の日付date
オブジェクトのコンストラクタ
time
オブジェクトtime
オブジェクトのコンストラクタ
timedelta
オブジェクトdatetime
,date
オブジェクトの引き算でtimedelta
オブジェクトを生成timedelta
オブジェクトのコンストラクタ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
オブジェクトが得られる。
import datetime
dt_now = datetime.datetime.now()
print(dt_now)
# 2018-02-02 18:31:13.271231
print(type(dt_now))
# <class 'datetime.datetime'>
print(dt_now.year)
# 2018
print(dt_now.hour)
# 18
datetimeオブジェクトのコンストラクタ
任意の日付、時刻のdatetime
オブジェクトを生成することも可能。
datetime
オブジェクトのコンストラクタは以下の通り。
datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
年year
、月month
、日day
は必須でそのほかは省略可能。省略した場合は初期値の0
になる。
dt = datetime.datetime(2018, 2, 1, 12, 15, 30, 2000)
print(dt)
# 2018-02-01 12:15:30.002000
print(dt.minute)
# 15
print(dt.microsecond)
# 2000
dt = datetime.datetime(2018, 2, 1)
print(dt)
# 2018-02-01 00:00:00
print(dt.minute)
# 0
datetimeオブジェクトからdateオブジェクトへの変換
datetime
オブジェクトはdate()
メソッドで次に説明するdate
オブジェクトに変換可能。
print(dt_now)
print(type(dt_now))
# 2018-02-02 18:31:13.271231
# <class 'datetime.datetime'>
print(dt_now.date())
print(type(dt_now.date()))
# 2018-02-02
# <class 'datetime.date'>
dateオブジェクト
date
オブジェクトは日付(年、月、日)の情報を持つオブジェクト。属性year
, month
, day
でアクセスできる。
date.today(): 今日の日付
date.today()
で現在の日付(今日の日付)のdate
オブジェクトが得られる。
d_today = datetime.date.today()
print(d_today)
# 2018-02-02
print(type(d_today))
# <class 'datetime.date'>
print(d_today.year)
# 2018
dateオブジェクトのコンストラクタ
date
オブジェクトのコンストラクタは以下の通り。
date(year, month, day)
すべて必須で、省略はできない。
d = datetime.date(2018, 2, 1)
print(d)
# 2018-02-01
print(d.month)
# 2
timeオブジェクト
time
オブジェクトは時刻(時、分、秒、マイクロ秒)の情報を持つオブジェクト。それらの情報に、属性hour
, minute
, second
, microsecond
でアクセスできる。
timeオブジェクトのコンストラクタ
time
オブジェクトのコンストラクタは以下の通り。
time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
すべて省略可能で、省略した場合は0
となる。
t = datetime.time(12, 15, 30, 2000)
print(t)
# 12:15:30.002000
print(type(t))
# <class 'datetime.time'>
print(t.hour)
# 12
t = datetime.time()
print(t)
# 00:00:00
timedeltaオブジェクト
timedelta
オブジェクトは二つの日時の時間差、経過時間を表すオブジェクト。日数、秒数、マイクロ秒数の情報を持ち、属性days
, seconds
, microseconds
でアクセスできる。また、total_seconds()
メソッドでトータルの秒数を取得することも可能。
datetime, dateオブジェクトの引き算でtimedeltaオブジェクトを生成
datetime
オブジェクト同士を引き算-
すると、timedelta
オブジェクトが得られる。
td = dt_now - dt
print(td)
# 1 day, 18:31:13.271231
print(type(td))
# <class 'datetime.timedelta'>
print(td.days)
# 1
print(td.seconds)
# 66673
print(td.microseconds)
# 271231
print(td.total_seconds())
# 153073.271231
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分後の時刻などを簡単に計算して取得できる。
d_1w = d_today - td_1w
print(d_1w)
# 2018-01-26
td_10d = datetime.timedelta(days=10)
print(td_10d)
# 10 days, 0:00:00
dt_10d = dt_now + td_10d
print(dt_10d)
# 2018-02-12 18:31:13.271231
td_50m = datetime.timedelta(minutes=50)
print(td_50m)
# 0:50:00
print(td_50m.seconds)
# 3000
dt_50m = dt_now + td_50m
print(dt_50m)
# 2018-02-02 19:21:13.271231
特定の日付までの日数(東京オリンピック開会式まであと何日)みたいな値を算出するのにも使える。
d_target = datetime.date(2020, 7, 24)
td = d_target - d_today
print(td)
# 903 days, 0:00:00
print(td.days)
# 903
時差(タイムゾーン)を扱う場合の処理についての詳細は以下の記事を参照。
strftime(): 日付、時間から文字列への変換
datetime
オブジェクト、date
オブジェクトの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
はロケールによって取得できる文字列が異なる。詳細は以下の記事を参照。
また、ISO 8601形式の文字列については専用のメソッドが用意されている。以下の記事を参照。
サンプルコード
print(dt_now.strftime('%Y-%m-%d %H:%M:%S'))
# 2018-02-02 18:31:13
print(d_today.strftime('%y%m%d'))
# 180202
print(d_today.strftime('%A, %B %d, %Y'))
# Friday, February 02, 2018
print(d_today.strftime('%Y年%m月%d日'))
# 2018年02月02日
print('日番号(1年の何日目か / 正月が001):', d_today.strftime('%j'))
print('週番号(週の始まりは日曜日 / 正月が00):', d_today.strftime('%U'))
print('週番号(週の始まりは月曜日 / 正月が00):', d_today.strftime('%W'))
# 日番号(1年の何日目か / 正月が001): 033
# 週番号(週の始まりは日曜日 / 正月が00): 04
# 週番号(週の始まりは月曜日 / 正月が00): 05
文字列ではなく数値を取得したい場合は、int()
で整数に変換すればOK。
week_num_mon = int(d_today.strftime('%W'))
print(week_num_mon)
print(type(week_num_mon))
# 5
# <class 'int'>
timedelta
オブジェクトと組み合わせて、例えば、任意のフォーマットで隔週の日付のリストを作るみたいなことも簡単。
d = datetime.date(2018, 2, 1)
td = datetime.timedelta(weeks=2)
n = 8
f = '%Y年%m月%d日'
l = []
for i in range(n):
l.append((d + i * td).strftime(f))
print(l)
# ['2018年02月01日', '2018年02月15日', '2018年03月01日', '2018年03月15日', '2018年03月29日', '2018年04月12日', '2018年04月26日', '2018年05月10日']
print('\n'.join(l))
# 2018年02月01日
# 2018年02月15日
# 2018年03月01日
# 2018年03月15日
# 2018年03月29日
# 2018年04月12日
# 2018年04月26日
# 2018年05月10日
リスト内包表記を使うともっとスマート。
l = [(d + i * td).strftime(f) for i in range(n)]
print(l)
# ['2018年02月01日', '2018年02月15日', '2018年03月01日', '2018年03月15日', '2018年03月29日', '2018年04月12日', '2018年04月26日', '2018年05月10日']
- 関連記事: Pythonリスト内包表記の使い方
strptime(): 文字列から日付、時間への変換
datetime
のstrptime()
を使うと、日付や時刻を表す文字列からdatetime
オブジェクトを生成できる。元の文字列に対応する書式化文字列を指定する必要がある。
こちらもISO 8601形式の文字列については専用のメソッドが用意されている(Python3.7以降)。以下の記事を参照。
サンプルコード
date_str = '2018/2/1 12:30'
date_dt = datetime.datetime.strptime(date_str, '%Y/%m/%d %H:%M')
print(date_dt)
# 2018-02-01 12:30:00
print(type(date_dt))
# <class 'datetime.datetime'>
取得したdatetime
オブジェクトでstrftime()
メソッドを使うことで、元の文字列と異なるフォーマットで日付や時刻を表すことができる。
print(date_dt.strftime('%Y年%m月%d日 %H時%M分'))
# 2018年02月01日 12時30分
datetime
オブジェクトに変換してしまえばtimedelta
オブジェクトとの演算も可能なので、例えば同じフォーマットで10日前の日付の文字列を生成したりすることも可能。
date_str = '2018年2月1日'
date_format = '%Y年%m月%d日'
td_10_d = datetime.timedelta(days=10)
date_dt = datetime.datetime.strptime(date_str, date_format)
date_dt_new = date_dt - td_10_d
date_str_new = date_dt_new.strftime(date_format)
print(date_str_new)
# 2018年01月22日