How to increment datetime by custom months in python without using library
Edit - based on your comment of dates being needed to be rounded down if there are fewer days in the next month, here is a solution:
import datetime
import calendar
def add_months(sourcedate, months):
month = sourcedate.month - 1 + months
year = sourcedate.year + month // 12
month = month % 12 + 1
day = min(sourcedate.day, calendar.monthrange(year,month)[1])
return datetime.date(year, month, day)
In use:
>>> somedate = datetime.date.today()
>>> somedate
datetime.date(2010, 11, 9)
>>> add_months(somedate,1)
datetime.date(2010, 12, 9)
>>> add_months(somedate,23)
datetime.date(2012, 10, 9)
>>> otherdate = datetime.date(2010,10,31)
>>> add_months(otherdate,1)
datetime.date(2010, 11, 30)
Also, if you're not worried about hours, minutes and seconds you could use date
rather than datetime
. If you are worried about hours, minutes and seconds you need to modify my code to use datetime
and copy hours, minutes and seconds from the source to the result.
Is there a simple way to increment a datetime object one month in Python?
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
The first Month next Year that starts on a Monday:
>>> month = rrule(YEARLY,dtstart=datetime.date(2023, 1, 1),bymonthday=1,byweekday=MO)[0]
>>> month.strftime('%Y-%m-%d : %B')
'2023-05-01 : May'
If you need the months that start on a Monday between 2 dates:
months = rrule(YEARLY,dtstart=datetime.date(2025, 1, 1),until=datetime.date(2030, 1, 1),bymonthday=1,byweekday=MO)
>>> for m in months:
... print(m.strftime('%Y-%m-%d : %B'))
...
2025-09-01 : September
2025-12-01 : December
2026-06-01 : June
2027-02-01 : February
2027-03-01 : March
2027-11-01 : November
2028-05-01 : May
2029-01-01 : January
2029-10-01 : October
This is by no means an exhaustive list of what is available.
Documentation is available here: https://dateutil.readthedocs.org/en/latest/
How to increment a datetime by one day?
date = datetime.datetime(2003,8,1,12,4,5)
for i in range(5):
date += datetime.timedelta(days=1)
print(date)
How do you add 3 months to a datetime.date object in python?
If you're looking for exact or "more precise" dates, you're probably better off checking out dateutil.
Quick example:
>>> from dateutil.relativedelta import relativedelta
>>> import datetime
>>> TODAY = datetime.date.today()
>>> TODAY
datetime.date(2012, 3, 6)
Now add 3 months to TODAY
, observe that it matches the day exactly (Note that relativedelta(months=3)
and relativedelta(month=3)
have different behaviors. Make sure to use months
for these examples!).
>>> three_mon_rel = relativedelta(months=3)
>>> TODAY + three_mon_rel
datetime.date(2012, 6, 6)
And it stays consistent throughout the course of a year. Literally every three months, on the day (had to keep adding because for some reason multiplying a relativedelta
and adding it to a datetime.date
object throws a TypeError
):
>>> TODAY + three_mon_rel + three_mon_rel
datetime.date(2012, 9, 6)
>>> TODAY + three_mon_rel + three_mon_rel + three_mon_rel
datetime.date(2012, 12, 6)
>>> TODAY + three_mon_rel + three_mon_rel + three_mon_rel + three_mon_rel
datetime.date(2013, 3, 6)
Whereas the mVChr's suggested solution, while definitely "good enough", drifts slightly over time:
>>> three_mon_timedelta = datetime.timedelta(days=3 * 365/12)
>>> TODAY + three_mon_timedelta
datetime.date(2012, 6, 5)
And over the course of a year, the day of month keeps sliding:
>>> TODAY + three_mon_timedelta * 2
datetime.date(2012, 9, 4)
>>> TODAY + three_mon_timedelta * 3
datetime.date(2012, 12, 4)
>>> TODAY + three_mon_timedelta * 4
datetime.date(2013, 3, 5)
how to set date variables in python in different formats?
You can do this quite nicely with datetime
from datetime import date
from dateutil.relativedelta import relativedelta
d = date(2020, 12, 1)
var1 = d.strftime("%b%y")
var2 = d.strftime("%Y %m")
nextd = d + relativedelta(months=1)
var3 = nextd.strftime("%Y-%m-01")
See here for more info about relativedelta, and see here for more info about strftime.
Python : How to add month to December 2012 and get January 2013?
The dateutil library is useful for calculations like that:
>>> start_date + relativedelta(months=2)
datetime.date(1984, 1, 23)
How can I extend month in Django
The easiest way to do this is to use the module dateutil
:
>>> from dateutil import relativedelta
>>> datetime.datetime.now() + relativedelta.relativedelta(months=1)
datetime.datetime(2021, 7, 27, 14, 30, 53, 111845)
>>> datetime.datetime.now() + relativedelta.relativedelta(months=4)
datetime.datetime(2021, 10, 27, 14, 32, 20, 238002)
Related Topics
Concatenating Two One-Dimensional Numpy Arrays
Convert Column to Date Format (Pandas Dataframe)
Force Python to Forego Native SQLite3 and Use the (Installed) Latest SQLite3 Version
Building Python with Ssl Support in Non-Standard Location
Is It Ok to Use Dashes in Python Files When Trying to Import Them
Regex to Extract Urls from Href Attribute in HTML with Python
Matplotlib: Specify Format of Floats for Tick Labels
Using Beautifulsoup to Extract Text Without Tags
Calling the "Source" Command from Subprocess.Popen
Purpose of Calling Function Without Brackets Python
(Z3Py) Checking All Solutions for Equation
Variable Assignment and Modification (In Python)
Why Does Python Assignment Not Return a Value
Database Does Not Update Automatically with MySQL and Python