note.nkmk.me

Pythonのdatetimeで日付や時間と文字列を変換(strftime, strptime)

Date: 2015-12-13 / Modified: 2018-02-02 / tags: Python

Pythonの標準ライブラリdatetimeを使って、日時(日付や時間・時刻)の処理ができる。日時と文字列を相互に変換するメソッドstrftime()strptime()で、様々なフォーマットの日付や時間を操作することが可能。

また、引き算や足し算などの演算も可能で、例えば、10日前とか3週間後の日付や50分後の時刻などを簡単に計算して取得できる。

ここでは、datetimeモジュールで利用できる、

  • datetime.datetime : 日時(日付と時刻)
  • datetime.date : 日付
  • datetime.time : 時刻
  • datetime.timedelta : 時間差・経過時間

のクラスのオブジェクトについて説明したあとで、日時と文字列を相互に変換するメソッドstrftime()strptime()について説明する。

ISO 8601形式の文字列との相互変換やタイムゾーンに関する処理についての詳細は以下の記事を参照。

スポンサーリンク

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オブジェクトを生成

deltatimeオブジェクト同士を引き算-すると、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

deltaオブジェクト同士の引き算でも同様にtimedeltaオブジェクトが得られる。

timedeltaオブジェクトのコンストラクタ

timedeltaオブジェクトのコンストラクタは以下の通り。

timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

すべて省略可能で、省略した場合は0となる。

なお、timedeltaオブジェクトが保持しているのは、あくまでも日数days, 秒数seconds, マイクロ秒数microsecondsの情報のみで、例えばweeks=1days=7と等しい。

td_1w = datetime.timedelta(weeks=1)
print(td_1w)
# 7 days, 0:00:00

print(td_1w.days)
# 7

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日']

strptime(): 文字列から日付、時間への変換

datetimestrptime()を使うと、日付や時刻を表す文字列から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日
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事