'Python get months start and end dates for a given year

I want to write a python function to get months start and end dates for a given year.

Sample Input : 2021

Expected output :

[(01-Jan-2021,31-Jan-2021), (01-Feb-2021,28-Feb-2021), (01-Mar-2021,31-Mar-2021), etc..)]


Solution 1:[1]

The end date is a trickier part here since it can be either 28, 29, 30 or 31,.

You can use the isleap functionality from the calendar module:

from calendar import isleap
import datetime
year = 2024
months_choices = []
for i in range(1, 13):
    month = datetime.date(2021, i, 1).strftime('%b')

    startDate = f"01-{month}-{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)

Output (for a leap year):

[('01-Jan-2024', '31-Jan-2024'), ('01-Feb-2024', '29-Feb-2024'), ('01-Mar-2024', '31-Mar-2024'), ('01-Apr-2024', '30-Apr-2024'), ('01-May-2024', '31-May-2024'), ('01-Jun-2024', '30-Jun-2024'), ('01-Jul-2024', '31-Jul-2024'), ('01-Aug-2024', '31-Aug-2024'), ('01-Sep-2024', '30-Sep-2024'), ('01-Oct-2024', '31-Oct-2024'), ('01-Nov-2024', '30-Nov-2024'), ('01-Dec-2024', '31-Dec-2024')]

Solution 2:[2]

you can use pandas date ranges, with appropriate frequency alias for month start and month end. Ex:

import pandas as pd

year, nMonths = "2020", 12

monthStart = pd.date_range(year, periods=nMonths, freq='MS').strftime("%d-%b-%Y")
monthEnd = pd.date_range(year, periods=nMonths, freq='M').strftime("%d-%b-%Y")

l = [(s,e) for s,e in zip(monthStart, monthEnd)]

l
[('01-Jan-2020', '31-Jan-2020'),
 ('01-Feb-2020', '29-Feb-2020'),
 ('01-Mar-2020', '31-Mar-2020'),
 ('01-Apr-2020', '30-Apr-2020'),
 ('01-May-2020', '31-May-2020'),
 ('01-Jun-2020', '30-Jun-2020'),
 ('01-Jul-2020', '31-Jul-2020'),
 ('01-Aug-2020', '31-Aug-2020'),
 ('01-Sep-2020', '30-Sep-2020'),
 ('01-Oct-2020', '31-Oct-2020'),
 ('01-Nov-2020', '30-Nov-2020'),
 ('01-Dec-2020', '31-Dec-2020')]

Solution 3:[3]

You're literally just checking if a year is a leap and then determining the length of Feb. This is probably a simple way of doing it:

import calendar

def MonthsStartAndEnd(year):
    # create dictionary of normal month lengths
    months = {
        'Jan': '31',
        'Feb': '28',
        'Mar': '31',
        'Apr': '30',
        'May': '31',
        'Jun': '30',
        'Jul': '31',
        'Aug': '31',
        'Sep': '30',
        'Oct': '31',
        'Nov': '30',
        'Dec': '31'
    }

    # check if the year is leap and if so update Feb to 29 days
    if calendar.isleap(year):
        months['Feb'] = '29'

    # return the formatted list of values
    return [f"01-{key}-{year},{value}-{key}-{year}" for key, value in months.items()]

print(MonthsStartAndEnd(2000))
print(MonthsStartAndEnd(2001))

#['01-Jan-2000,31-Jan-2000', '01-Feb-2000,29-Feb-2000', '01-Mar-2000,31-Mar-2000', '01-Apr-2000,31-Apr-2000', '01-May-2000,31-May-2000', '01-Jun-2000,31-Jun-2000', '01-Jul-2000,31-Jul-2000', '01-Aug-2000,31-Aug-2000', '01-Sep-2000,31-Sep-2000', '01-Oct-2000,31-Oct-2000', '01-Nov-2000,31-Nov-2000', '01-Dec-2000,31-Dec-2000']
['01-Jan-2001,31-Jan-2001', '01-Feb-2001,28-Feb-2001', '01-Mar-2001,31-Mar-2001', '01-Apr-2001,31-Apr-2001', '01-May-2001,31-May-2001', '01-Jun-2001,31-Jun-2001', '01-Jul-2001,31-Jul-2001', '01-Aug-2001,31-Aug-2001', '01-Sep-2001,31-Sep-2001', '01-Oct-2001,31-Oct-2001', '01-Nov-2001,31-Nov-2001', '01-Dec-2001,31-Dec-2001']

 

Solution 4:[4]

If you are using Pandas, period_range is best suited for this (no zipping date series required!):

import pandas as pd
periods = pd.period_range('1/1/2016', freq='M', periods=12) 
print([(p.start_time.strftime('%d-%b-%Y'), p.end_time.strftime('%d-%b-%Y')) for p in periods])
# outputs: [('01-Jan-2016', '31-Jan-2016'), ('01-Feb-2016', '29-Feb-2016'), ...]

All pandas date/time functionality can be found here: https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Krishna Chaurasia
Solution 2
Solution 3
Solution 4 Bemis