Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a simple way to increment a datetime object one month in Python? [duplicate]

So I am trying to find a way to increment a datetime object by one month. However, it seems this is not so simple, according to this question.

I was hoping for something like:

import datetime as dt  now = dt.datetime.now() later = now + dt.timedelta(months=1) 

But that doesn't work. I was also hoping to be able to go to the same day (or the closest alternative) in the next month if possible. For example, a datetime object set at January 1st would increment to Feb 1st whereas a datetime object set at February 28th would increment to March 31st as opposed to March 28th or something.

To be clear, February 28th would (typically) map to March 31st because it is the last day of the month, and thus it should go to the last day of the month for the next month. Otherwise it would be a direct link: the increment should go to the day in the next month with the same numbered day.

Is there a simple way to do this in the current release of Python?

like image 864
d0rmLife Avatar asked Jan 28 '16 16:01

d0rmLife


People also ask

How do I add months to a datetime object?

date() method is used to create a date object by specifying the year, month, and day, and by using the relativedelta() method we add the number of months, and finally, we get a new datetime object.


1 Answers

Check out from dateutil.relativedelta import * for adding a specific amount of time to a date, you can continue to use timedelta for the simple stuff i.e.

import datetime from dateutil.relativedelta import * use_date = datetime.datetime.now()  use_date = use_date + datetime.timedelta(minutes=+10) use_date = use_date + datetime.timedelta(hours=+1) use_date = use_date + datetime.timedelta(days=+1) use_date = use_date + datetime.timedelta(weeks=+1) 

or you can start using relativedelta

use_date = use_date+relativedelta(months=+1)  use_date = use_date+relativedelta(years=+1) 

for the last day of next month:

use_date = use_date+relativedelta(months=+1) use_date = use_date+relativedelta(day=31) 

Right now this will provide 29/02/2016

for the penultimate day of next month:

use_date = use_date+relativedelta(months=+1) use_date = use_date+relativedelta(day=31) use_date = use_date+relativedelta(days=-1) 

last Friday of the next month:

use_date = use_date+relativedelta(months=+1, day=31, weekday=FR(-1)) 

2nd Tuesday of next month:

new_date = use_date+relativedelta(months=+1, day=1, weekday=TU(2)) 

As @mrroot5 points out dateutil's rrule functions can be applied, giving you an extra bang for your buck, if you require date occurences.
for example:
Calculating the last day of the month for 9 months from the last day of last month.
Then, calculate the 2nd Tuesday for each of those months.

from dateutil.relativedelta import * from dateutil.rrule import * from datetime import datetime use_date = datetime(2020,11,21)  #Calculate the last day of last month use_date = use_date+relativedelta(months=-1) use_date = use_date+relativedelta(day=31)  #Generate a list of the last day for 9 months from the calculated date x = list(rrule(freq=MONTHLY, count=9, dtstart=use_date, bymonthday=(-1,))) print("Last day") for ld in x:     print(ld)  #Generate a list of the 2nd Tuesday in each of the next 9 months from the calculated date print("\n2nd Tuesday") x = list(rrule(freq=MONTHLY, count=9, dtstart=use_date, byweekday=TU(2))) for tuesday in x:     print(tuesday)  Last day 2020-10-31 00:00:00 2020-11-30 00:00:00 2020-12-31 00:00:00 2021-01-31 00:00:00 2021-02-28 00:00:00 2021-03-31 00:00:00 2021-04-30 00:00:00 2021-05-31 00:00:00 2021-06-30 00:00:00  2nd Tuesday 2020-11-10 00:00:00 2020-12-08 00:00:00 2021-01-12 00:00:00 2021-02-09 00:00:00 2021-03-09 00:00:00 2021-04-13 00:00:00 2021-05-11 00:00:00 2021-06-08 00:00:00 2021-07-13 00:00:00 

rrule could be used to find the next date occurring on a particular day.
e.g. the next 1st of January occurring on a Monday (Given today is the 4th November 2021)

from dateutil.relativedelta import * from dateutil.rrule import * from datetime import * year = rrule(YEARLY,dtstart=datetime.now(),bymonth=1,bymonthday=1,byweekday=MO)[0].year year 2024 

or the next 5 x 1st of January's occurring on a Monday

years = rrule(YEARLY,dtstart=datetime.now(),bymonth=1,bymonthday=1,byweekday=MO)[0:5] for i in years:print(i.year) ...  2024 2029 2035 2046 2052 

This is by no means an exhaustive list of what is available. Documentation is available here: https://dateutil.readthedocs.org/en/latest/

like image 111
Rolf of Saxony Avatar answered Oct 04 '22 16:10

Rolf of Saxony