日付と日付時刻の変更¶
日付と日付時刻の変更方法の紹介をします。
日付と日付時刻は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のデータは、日付時刻のデータだけでなく日付データに対しても使えます。
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
のいずれかです。
MO
とMO(1)
は同じ意味です。また、すでに月曜であればMO
とMO(-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です。
実行例その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になります。