日付と日付時刻の変更

日付と日付時刻の変更方法の紹介をします。

日付と日付時刻はdatetimeモジュールのdateとdatetimeを使います。

timedeltaによる変更

日付と日付時刻のデータに対し、datetimeモジュールのtimedeltaを足したり引いたりできます。これにより時刻を進めたり戻したりできます。

下記は、2021年10月1日を表す日付時刻の変数dtに対し、10日と5秒後を求めて表示する例です。

from datetime import datetime, timedelta

print(datetime(2021, 10, 1) + timedelta(10, 5))  # 2021-10-11 00:00:05

timedeltaのデータは、timedelta(日数, 秒数)のように作成します。他にも、時間数、分数、週数なども指定できます。 また、timedeltaのデータは、日付時刻のデータだけでなく日付データに対しても使えます。

参考:datetime --- 基本的な日付型および時間型

timedeltaを使うと、日付と日付時刻の「X日後」「X日前」を計算できます。 しかし、「Xヶ月後」「X年後」を計算することはできません。この場合は次節のようにrelativedeltaを使います。

relativedeltaによる変更

relativedeltaのデータは、timedeltaと同じように日付や日付時刻に足したり引いたりできます。 relativedeltaは、dateutil.relativedeltaモジュールで定義されています。

なお、dateutilは標準モジュールではないため、下記のようにpython-dateutilモジュールをインストールして使います。

pip install python-dateutil

relativedeltaを使うと、「Xヶ月後」「X年後」を計算できます。それだけではなく、作成時に指定できる項目は多岐に渡ります。

relativedeltaデータの作成方法

relativedeltaは、絶対値相対値その他の3種類の値を設定できます。 設定可能な値は、以下の表の通りですが、設定しない場合は無視されます(表は引数の順番になっています)。

種類

仮引数

意味

その他

dt1

日付時刻1

その他

dt2

日付時刻2

相対値

years

相対値

months

相対値

days

相対値

leapdays

-1の場合、うるう日を無視する

相対値

weeks

相対値

hours

相対値

minutes

相対値

seconds

相対値

microseconds

マイクロ秒

絶対値

year

絶対値

month

絶対値

day

その他

weekday

N週の曜日

絶対値

yearday

前年大晦日からの日数

絶対値

nlyearday

前年大晦日からのうるう日を無視した日数

絶対値

hour

絶対値

minute

絶対値

second

絶対値

microsecond

マイクロ秒

dt1, dt2の両方が指定されると、dt1 - dt2の相対値となります。また、そのときはその他の指定は無視されます。

leapdaysは、yearday指定時に内部で使われており、使用はおすすめしません。

weekday以外の相対値は整数です。絶対値はNoneまたは整数です。 weekdayは、曜日を意味するMO, TU, WE, TH, FR, SA, SUのいずれかです。

MOMO(1)は同じ意味です。また、すでに月曜であればMOMO(-1)は同じ結果です。 MO(2)とすると2回目の月曜日という意味になります。 MO(-2)とすると2回前の月曜日という意味になります。 MO(0)は使いません。

演算ルール

ここでは、relativedeltaのシンプルな使い方を紹介します。詳細はdateutil.relativedelta を参照ください。

  • 対象値 + 更新値または対象値 - 更新値で対象値を更新します。対象値は日付または日付時刻です。更新値はrelativedeltaのデータです(後述の実行例その1参照)。

  • 最初に、対象値に「更新値の絶対値」を上記の表の上から順番に設定します(後述の実行例その2参照)。

  • 次に、対象値に「更新値の相対値」を上記の表の上から順番に加算または減算します。

  • 最後に、更新値にweekdayがあればその曜日になるように加算または減算します。すでにその曜日であれば、変化しません(後述の実行例その3参照)。

  • relativedeltaに数値をかけると、相対値をその倍数にします。そのとき、小数点以下は切り捨てられて整数になります(後述の実行例その1参照)。

演算

  • dateにrelativedeltaを足したり引いたりしたものは、dateです。ただし、0時0分以外になった場合は、datetimeになります。

  • datetimeにrelativedeltaを足したり引いたりしたものは、datetimeです。

  • 「relativedelta * 数字」は、relativedeltaです。

  • 「relativedelta + relativedelta」や「relativedelta - relativedelta」は、relativedeltaです。

参考:dateutil.relativedelta

実行例その1

from datetime import date
from dateutil.relativedelta import relativedelta

dt = date(2020, 1, 31)  # dateのデータ
rd = relativedelta(months=1)  # relativedeltaのデータ

print(dt - rd)  # 2019-12-31
print(dt + rd)  # 2020-02-29
print(dt + rd * 3)  # 2020-04-30
  • 2020-01-31の日付を表す変数dtを作成します。

  • rd = relativedelta(months=1)は、「1ヶ月」を意味します(monthsは相対値です)。

  • dt - rdは1ヶ月前なので、2019-12-31です。

  • dt + rdは1ヶ月後です。2020-02-31は存在しないので2月の最終日の2020-02-29になります。

  • rd * 3は「3ヶ月」になります。したがって、dt + rd * 3は、3ヶ月後の2020-04-30です。

実行例その2

dt = date(2020, 1, 31)  # dateのデータ

rd1 = relativedelta(day=3)
print(dt + rd1)  # 2020-01-03

rd2 = relativedelta(day=3, yearday=7)
print(dt + rd2)  # 2020-01-07
  • 2020-01-31の日付を表す変数dtを作成します。

  • dt + rd1は、rd1の絶対値である引数day=3の指定により、2020-01-03になります。

  • dt + rd2は、rd2の引数の中から、表の上にある方のday=3の指定により、一旦、2020-01-03になります。その後、yearday=7の指定により、2020-01-07になります。つまり、yeardayの方が優先されます。

実行例その3

from dateutil.relativedelta import FR, SA

dt = date(2020, 1, 31)  # dateのデータ

rd1 = relativedelta(weekday=SA)
print(dt + rd1)  # 2020-02-01

rd2 = relativedelta(weekday=FR)
print(dt + rd2)  # 2020-01-31
  • 2020-01-31の日付を表す変数dtを作成します。

  • dt + rd1は、rd1の引数weekday=SAの指定により、次の土曜日の2020-02-01になります。

  • dt + rd2は、rd2の引数weekday=FRの指定がありますが、2020-01-31が金曜日なので、変わらずに2020-01-31になります。

当コンテンツの知的財産権は株式会社ビープラウドに所属します。詳しくは利用規約をご確認ください。