Python: Find the starting Sunday for all the weeks in a month
In this post we’re going to learn how to find the dates of all the Sundays in a given month, as well as the Sunday immediately preceding the 1st day in the month, assuming that day isn’t a Sunday.
Let’s start by importing some libraries that we’re going to use in this blog post:
from dateutil import parser
import datetime
import calendar
Next we need to find the first day of the current month, which we can do with the following code:
today = datetime.date.today()
start = today.replace(day=1)
>>> start
datetime.date(2020, 4, 1)
Now we need to find the last day of the month. I found a cool StackOverflow thread that suggested lots of different approaches. I liked the following one best:
weekday, last_day = calendar.monthrange(now.year, now.month)
>>> last_day
30
We can now create a new date by updating the day to be last_day
:
end = today.replace(day=last_day)
And now let’s output the start
and end
variables:
>>> start
datetime.date(2020, 4, 1)
>>> end
datetime.date(2020, 4, 30)
So far so good!
Our next task is to create a collection containing all the days between these dates.
One way to do this is to iterate over a range of the number of days between these dates, and then add the timedelta of the increasing number of days to the start date.
We can compute the number of days between these two dates by using a subtraction operation, which will return a timedelta
object.
We’ll then call the days
property on that:
>>> end - start
datetime.timedelta(days=29)
>>> (end - start).days
29
Now let’s create a range from 0 to that number of days and create a list containing the dates between these two dates:
>>> [start + datetime.timedelta(day) for day in range(0, (end - start).days + 1)]
[datetime.date(2020, 4, 1), datetime.date(2020, 4, 2), datetime.date(2020, 4, 3), datetime.date(2020, 4, 4), datetime.date(2020, 4, 5), datetime.date(2020, 4, 6), datetime.date(2020, 4, 7), datetime.date(2020, 4, 8), datetime.date(2020, 4, 9), datetime.date(2020, 4, 10), datetime.date(2020, 4, 11), datetime.date(2020, 4, 12), datetime.date(2020, 4, 13), datetime.date(2020, 4, 14), datetime.date(2020, 4, 15), datetime.date(2020, 4, 16), datetime.date(2020, 4, 17), datetime.date(2020, 4, 18), datetime.date(2020, 4, 19), datetime.date(2020, 4, 20), datetime.date(2020, 4, 21), datetime.date(2020, 4, 22), datetime.date(2020, 4, 23), datetime.date(2020, 4, 24), datetime.date(2020, 4, 25), datetime.date(2020, 4, 26), datetime.date(2020, 4, 27), datetime.date(2020, 4, 28), datetime.date(2020, 4, 29), datetime.date(2020, 4, 30)]
Note
|
The range function doesn’t include the upper bound, so we had to add 1 so that the end date is included.
|
So far so good.
Now we want to filter the list to only return Sundays.
We can use the isoweekday
function to do this.
Sundays are represented by a value of 7, which gives us the following code:
>>> [date for date in [start + datetime.timedelta(day) for day in range(0, (end - start).days + 1)] if date.isoweekday() == 7]
[datetime.date(2020, 4, 5), datetime.date(2020, 4, 12), datetime.date(2020, 4, 19), datetime.date(2020, 4, 26)]
We’ve now got all the Sundays in April.
And our final step is get the Sunday preceding April 1st.
We can work this out by subtracting the isoweekday
of our start
variable:
>>> start.isoweekday()
3
>>> start - datetime.timedelta(days = start.isoweekday())
datetime.date(2020, 3, 29)
We can now update our start
date.
This leads to the following code to compute start and end dates:
today = datetime.date.today()
weekday, last_day = calendar.monthrange(now.year, now.month)
start = today.replace(day=1)
start = start - datetime.timedelta(days = start.isoweekday())
end = today.replace(day=last_day)
Let’s quickly check those dates:
>>> start
datetime.date(2020, 3, 29)
>>> end
datetime.date(2020, 4, 30)
And now we can find all the Sundays between these dates:
>>> [date for date in [start + datetime.timedelta(day) for day in range(0, (end - start).days + 1)] if date.isoweekday() == 7]
[datetime.date(2020, 3, 29), datetime.date(2020, 4, 5), datetime.date(2020, 4, 12), datetime.date(2020, 4, 19), datetime.date(2020, 4, 26)]
And we’re done!
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.