This answer is a bit long but it uses only datetime
and calendar
module to get the expected result:
import calendar
from datetime import datetime, date
def generate_rolling_date(input_date, number_of_dates):
"""
Generate Rolling Date
:param input_date: Input Date (e.g. '01-Feb-21')
:param number_of_dates: Number of rolling date to generate
:return:
"""
# Convert input_date to datetime according to the format
parsed_date = datetime.strptime(input_date, "%d-%b-%y")
# Separate Day, Month and Year
parsed_day = parsed_date.day
parsed_month = parsed_date.month
parsed_year = parsed_date.year
# Initialize an empty output list
output = []
# using calendar module, gets the total number of days i.e. last day in parsed_month
_, num_days = calendar.monthrange(parsed_year, parsed_month)
# Check if the parsed_day is the last day of the month or not, according to that set the start_date flag
start_date = False if num_days == parsed_day else True
# Loop through the number_of_dates to generate the rolling dates
for i in range(number_of_dates):
# If the parsed_month value is 0, then decrease the parsed_year by 1 and set the parsed_month value to 12
if parsed_month == 0:
parsed_year -= 1
parsed_month = 12
# Get the total number of days i.e. last day in parsed_month
_, num_days = calendar.monthrange(parsed_year, parsed_month)
# If start_date, then get the first day of the month and set start_date to False,
# so we can get the last day of month in the next loop
if start_date:
# Get the first day of the month
selected_day = date(parsed_year, parsed_month, 1)
start_date = False
else:
# Get the last day of the month
selected_day = date(parsed_year, parsed_month, num_days)
# After getting the last day of the month, decrease the parsed_month by 1 to get the previous month
parsed_month -= 1
start_date = True
# Append selected_day to the output
output.append(date.strftime(selected_day, "%d-%b-%y"))
# Return the output
return output
print(generate_rolling_date("01-Feb-21", 8))
Which gives the following output:
['01-Feb-21',
'28-Feb-21',
'01-Jan-21',
'31-Jan-21',
'01-Dec-20',
'31-Dec-20',
'01-Nov-20',
'30-Nov-20']