Given a particular date, say 2011-07-02, how can I find the date of the next Monday (or any weekday day for that matter) after that date?
11 Answers
import datetime
def next_weekday(d, weekday):
days_ahead = weekday - d.weekday()
if days_ahead <= 0: # Target day already happened this week
days_ahead += 7
return d + datetime.timedelta(days_ahead)
d = datetime.date(2011, 7, 2)
next_monday = next_weekday(d, 0) # 0 = Monday, 1=Tuesday, 2=Wednesday...
print(next_monday)
Here's a succinct and generic alternative to the slightly weighty answers above.
# Returns the date of the next given weekday after
# the given date. For example, the date of next Monday.
# NB: if it IS the day we're looking for, this returns 0.
# consider then doing onDay(foo, day + 1).
onDay = lambda date, day: date + datetime.timedelta(days=(day-date.weekday()+7)%7)
This is example of calculations within ring mod 7.
import datetime
def next_day(given_date, weekday):
day_shift = (weekday - given_date.weekday()) % 7
return given_date + datetime.timedelta(days=day_shift)
now = datetime.date(2018, 4, 15) # sunday
names = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday',
'saturday', 'sunday']
for weekday in range(7):
print(names[weekday], next_day(now, weekday))
will print:
monday 2018-04-16
tuesday 2018-04-17
wednesday 2018-04-18
thursday 2018-04-19
friday 2018-04-20
saturday 2018-04-21
sunday 2018-04-15
As you see it's correctly give you next monday, tuesday, wednesday, thursday friday and saturday. And it also understood that 2018-04-15 is a sunday and returned current sunday instead of next one.
I'm sure you'll find this answer extremely helpful after 7 years ;-)
Another simple elegant solution is to use pandas offsets.
I find it very helpful and robust when playing with dates.
- If you want the first Sunday just modify the frequency to freq='W-SUN'.
- If you want a couple of next Sundays, change the offsets.Day(days).
- Using pandas offsets allow you to ignore holidays, work only with Business Days and more.
You can also apply this method easily on a whole DataFrame using apply method.
# Getting the closest monday from a given date
closest_monday = pd.date_range(start=date, end=date + offsets.Day(6), freq='W-MON')[0]
# Adding a 'ClosestMonday' column with the closest monday for each row in a pandas df using apply
# Require you to have a 'Date' column in your df
def get_closest_monday(row):
return pd.date_range(start=row.Date, end=row.Date + offsets.Day(6), freq='W-MON')[0]
df['ClosestMonday'] = df.apply(lambda row: get_closest_monday(row), axis=1)
Another alternative uses rrule
from dateutil.rrule import rrule, WEEKLY, MO
from datetime import date
next_monday = rrule(freq=WEEKLY, dtstart=date.today(), byweekday=MO, count=1)[0]
rrule docs: https://dateutil.readthedocs.io/en/stable/rrule.html
This will give the first next Monday after given date:
import datetime
def get_next_monday(year, month, day):
date0 = datetime.date(year, month, day)
next_monday = date0 + datetime.timedelta(7 - date0.weekday() or 7)
return next_monday
print get_next_monday(2011, 7, 2)
print get_next_monday(2015, 8, 31)
print get_next_monday(2015, 9, 1)
2011-07-04
2015-09-07
2015-09-07