Python – Last business day of every month in year
Last Updated :
17 Apr, 2023
Given a year and weekday number, the task is to write a Python program to extract each date of the month corresponding to the weekday.
Input : year = 1997, weekdy = 5
Output : [’25/1/1997′, ’22/2/1997′, ’29/3/1997′, ’26/4/1997′, ’31/5/1997′, ’28/6/1997′, ’26/7/1997′, ’30/8/1997′, ’27/9/1997′, ’25/10/1997′, ’29/11/1997′, ’27/12/1997′]
Explanation : 5 is friday. Last weekday of january 1997 which is friday is 25.
Input : year = 1996, weekdy = 4
Output : [’26/1/1996′, ’23/2/1996′, ’29/3/1996′, ’26/4/1996′, ’31/5/1996′, ’28/6/1996′, ’26/7/1996′, ’30/8/1996′, ’27/9/1996′, ’25/10/1996′, ’29/11/1996′, ’27/12/1996′]
Explanation : 4 is thursday. Last weekday of january 1997 which is thursday is 26.
Method #1 : Using loop + max() + calendar.monthcalendar
In this, we perform the task of getting each month calendar using monthcalendar() from the calendar library. Each weekday date is extracted and the maximum of it, being the maximum of the whole month is the last weekday, hence extracted.
Python3
import calendar
year = 1997
print ( "The original year : " + str (year))
weekdy = 5
res = []
for month in range ( 1 , 13 ):
res.append( str ( max (week[weekdy]
for week in calendar.monthcalendar(year, month))) +
"/" + str (month) + "/" + str (year))
print ( "Last weekdays of year : " + str (res))
|
Output:
The original year : 1997
Last weekdays of year : [’25/1/1997′, ’22/2/1997′, ’29/3/1997′, ’26/4/1997′, ’31/5/1997′, ’28/6/1997′, ’26/7/1997′, ’30/8/1997′, ’27/9/1997′, ’25/10/1997′, ’29/11/1997′, ’27/12/1997′]
Method #2: Using list comprehension
Similar to the above method, the only difference being the usage of list comprehension for a compact solution.
Python3
import calendar
year = 1997
print ( "The original year : " + str (year))
weekdy = 5
res = [ str ( max (week[weekdy]
for week in calendar.monthcalendar(year, month))) +
"/" + str (month) + "/" + str (year) for month in range ( 1 , 13 )]
print ( "Last weekdays of year : " + str (res))
|
Output:
The original year : 1997
Last weekdays of year : [’25/1/1997′, ’22/2/1997′, ’29/3/1997′, ’26/4/1997′, ’31/5/1997′, ’28/6/1997′, ’26/7/1997′, ’30/8/1997′, ’27/9/1997′, ’25/10/1997′, ’29/11/1997′, ’27/12/1997′]
The time complexity of this program is O(12*w*m) where w is the number of weekdays and m is the number of months.
The auxiliary space complexity of the program is O(m) where m is the number of months.
Method #3: Using pandas library
Use the pandas library to create a date range for the entire year, and then filter out the last weekday of each month using the weekday and is_month_end methods. Here’s how you can modify the code using pandas.
Python3
import pandas as pd
year = 1997
print ( "The original year : " + str (year))
weekdy = 4
dates = pd.date_range(start = f '{year}-01-01' , end = f '{year}-12-31' , freq = 'D' )
res = [ str (date.date()) for date in dates[(dates.weekday = = weekdy) & (dates.is_month_end)]]
print ( "Last weekdays of year : " + str (res))
|
The original year : 1997
Last weekdays of year : ['1997-01-31', '1997-02-28', '1997-10-31']
Time complexity: O(n), where n is the number of days in the given year.
Auxiliary space: O(n), as we create a pandas date range object for the entire year and store it in memory.
Method #4: Using datetime and timedelta from datetime module
step-by-step approach :
- First, we initialize the year and weekday variables. In this example, year is set to 1997 and weekday is set to 4, which represents Friday.
- We create an empty list called last_weekdays to store the last weekdays of each month.
- We iterate over the months of the year using a for loop. The loop runs 12 times, once for each month.
- For each month, we get the last day of the month using the datetime and timedelta classes. We start by creating a datetime object for the first day of the month using the datetime class.
- We then add 32 days to this datetime object using the timedelta class. This brings us to a date beyond the end of the month, which ensures that we get the last day of the month even if it’s a leap year (since February can have 29 days).
- We replace the day component of the resulting datetime object with 1 and then subtract 1 day using timedelta to get the last day of the month.
- We check if the last day of the month is the same weekday as the desired weekday. If it is, we append the date to the last_weekdays list.
- Finally, we print the results.
Python3
from datetime import datetime, timedelta
year = 1997
weekday = 4
last_weekdays = []
for month in range ( 1 , 13 ):
last_day = datetime(year, month, 1 ) + timedelta(days = 32 )
last_day = last_day.replace(day = 1 ) - timedelta(days = 1 )
if last_day.weekday() = = weekday:
last_weekdays.append(last_day.date())
print (f "Last weekdays of year: {last_weekdays}" )
|
Output
Last weekdays of year: [datetime.date(1997, 1, 31), datetime.date(1997, 2, 28), datetime.date(1997, 10, 31)]
The time complexity of this method is O(1) since it only needs to iterate over the months once.
The auxiliary space is O(1) since only a few variables are stored in memory.
Method #5: Using dateutil library
Step-by-step approach:
- Import the necessary module from dateutil library
- Initialize year and weekday (same as in the original code)
- Create a list of datetime objects for every month in the year
- Filter the list to include only the datetime objects for the last weekday of the month
- Format the datetime objects as strings in the required format
- Return the list of formatted strings
Python3
from dateutil import rrule, relativedelta
from datetime import datetime
year = 1997
print ( "The original year : " + str (year))
weekdy = 5
months = [datetime(year, month, 1 ) for month in range ( 1 , 13 )]
last_weekdays = [dt.strftime( '%d/%m/%Y' ) for dt in months if dt.weekday() = = weekdy
and dt + relativedelta.relativedelta(months = 1 , days = - 1 )]
print ( "Last weekdays of year : " + str (last_weekdays))
|
OUTPUT ;
The original year : 1997
Last weekdays of year : ['01/02/1997', '01/03/1997', '01/11/1997']
Time complexity: O(1) as the list of datetime objects has a fixed length of 12 (number of months)
Auxiliary space: O(1) as the memory usage is constant and does not depend on the size of input.
Please Login to comment...