This is the code I have so far:
from calendar import isleap
import datetime
year =2021
month= 4
year2=2022
months_choices=[]
for i in range(1, 5):
month = datetime.date(2021, i, 1).strftime('%b')
startDate = f"01-Dec-{year}"
if month in ["Jan", "Mar", "May", "Jul", "Aug", "Oct", "Dec"]:
endDate = f"31-{month}-{year}"
elif month in ["Apr", "Jun", "Sep", "Nov"]:
endDate = f"30-{month}-{year}"
else:
isLeap = isleap(1900)
if isLeap:
endDate = f"29-{month}-{year}"
else:
endDate = f"28-{month}-{year}"
months_choices.append((startDate, endDate))
print(months_choices)
I would like my output to print as [('01-Dec-2021', '31-Dec-2021'), ('01-Jan-2022', '31-Jan-2022'), ('01-Feb-2022', '28-Feb-2022'), ('01-March-2021', '31-March-2021'),('01-April-2021', '30-Apr-2021')], but it prints like below.
print(months_choices)
[('01-Dec-2021', '31-Jan-2021'), ('01-Dec-2021', '28-Feb-2021'), ('01-Dec-2021', '31-Mar-2021'), ('01-Dec-2021', '30-Apr-2021')]
CodePudding user response:
The calendar module has some very useful features that you could utilise.
As a starting point you would benefit from having a function that takes the start month/year and end month/year.
Something like this:
from calendar import monthrange, month_abbr
def range_ok(start_month, start_year, end_month, end_year):
if start_month < 1 or start_month > 12 or end_month < 1 or end_month > 12:
return False
if start_year > end_year or (start_year == end_year and start_month > end_month):
return False
return True
def func(start_month, start_year, end_month, end_year):
result = []
while range_ok(start_month, start_year, end_month, end_year):
mn = month_abbr[start_month]
d1 = f'01-{mn}-{start_year}'
sd = monthrange(start_year, start_month)[1]
d2 = f'{sd}-{mn}-{start_year}'
result.append((d1, d2))
if (start_month := start_month 1) > 12:
start_month = 1
start_year = 1
return result
print(func(12, 2021, 4, 2022))
Output:
[('01-Dec-2021', '31-Dec-2021'), ('01-Jan-2022', '31-Jan-2022'), ('01-Feb-2022', '28-Feb-2022'), ('01-Mar-2022', '31-Mar-2022'), ('01-Apr-2022', '30-Apr-2022')]
CodePudding user response:
EDIT
As requested in the comments, in order to generate the date range between two dates, the solution can be adjusted like this:
import pandas as pd
import calendar
from datetime import date
start_date = '2021-12-01'
end_date = '2022-04-30'
date_range = pd.date_range(start_date,end_date,
freq='MS').map(lambda x: (x.year, x.month)).tolist()
def get_dates(year, month):
return (date(year, month, 1).strftime("%d-%b-%Y"),
date(year,
month,
calendar.monthrange(year, month)[1]
).strftime("%d-%b-%Y"))
[get_dates(year, month)
for year, month in date_range]
Original solution
Use calendar.monthrange(YEAR, MONTH)
to get the last day of the month. It handles the leap years for you.
import calendar
from datetime import date
years = [2021,2022]
months = [range(12, 13), range(1,5)]
def get_dates(year, month):
return (date(year, month, 1).strftime("%d-%b-%Y"),
date(year,
month,
calendar.monthrange(year, month)[1]
).strftime("%d-%b-%Y"))
[get_dates(year, month)
for year, month_range in zip(years, months)
for month in month_range]
Output:
[('01-Dec-2021', '31-Dec-2021'),
('01-Jan-2022', '31-Jan-2022'),
('01-Feb-2022', '28-Feb-2022'),
('01-Mar-2022', '31-Mar-2022'),
('01-Apr-2022', '30-Apr-2022')]