Home > database >  How to take months as inputs then determine start and end date for each month? I also want to go fro
How to take months as inputs then determine start and end date for each month? I also want to go fro

Time:04-16

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')]
  • Related