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

Modified: | Tags: Python, 日時処理

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

引き算や足し算も可能で、例えば、10日前の日付や50分後の時刻などを計算できる。

datetimeモジュールでは以下のクラスが定義されている。モジュール名と日時を扱うクラス名が同じdatetimeなので混同しないように要注意。

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

ここでは、それぞれのクラスについて説明したあとで、日時と文字列を相互に変換するメソッドstrftime()strptime()について説明する。

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

また、プレーンテキストや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=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分後の時刻などを簡単に計算できる。

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で日付に関する書式コードを使ってもエラーにはならず、初期値(01)とみなされる。

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オブジェクトと組み合わせて、例えば、任意のフォーマットで隔週の日付のリストを作るみたいなことも簡単にできる。

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

関連カテゴリー

関連記事