1

I want to generate a python list containing all months occurring between two dates, which is separated by year in array as follow:

startdate = "2014-10-10"  # input start date
enddate = "2016-01-07"  # input end date
month_list = [['Oct-14', 'Nov-14', 'Dec-14'], ['Jan-15', 'Feb-15', 'Mar-15', 'Apr-15', 'May-15', 'Jun-15', 'Jul-15', 'Aug-15', 'Sep-15', 'Oct-15', 'Nov-15', 'Dec-15'], ['Jan-16']]  # output

i tried this but it display only two year interval in array

import calendar
from datetime import *
startdate = datetime.strptime("2015-09-10", "%Y-%m-%d")
enddate = datetime.strptime("2016-5-15", "%Y-%m-%d")
month_str = calendar.month_name
curryear = startdate.year
months = []
yearss=[]
temp=[]
while startdate < enddate:
    month = startdate.month
    year = startdate.year
    day = startdate.day
    mon_str = month_str[month][0:3]
    next_month = month + 1 if month != 12 else 1
    if curryear == year:
        months.append("{0}-{1}".format(mon_str, str(year)[-2:]))
        startdate = startdate.replace(month=next_month, year=year)
    next_year = year+1 if next_month==1 else year
    if curryear != next_year:
        startdate = startdate.replace(month=next_month, year=next_year)
        temp.append("{0}-{1}".format(mon_str, str(next_year)[-2:]))
months.append(temp)
print(months)

Output: ['Sep-15', 'Oct-15', 'Nov-15', 'Dec-15', ['Dec-16', 'Jan-16', 'Feb-16', 'Mar-16', 'Apr-16', 'May-16']]

2 Answers2

1

Solution without pandas.
(you can also use it without dateutils)
(but then you've to manually count the months)

import datetime 
from dateutil.relativedelta import relativedelta

startdate = datetime.datetime.strptime("2014-10-10", "%Y-%m-%d")
enddate = datetime.datetime.strptime("2016-01-07", "%Y-%m-%d")

# truncate the dates
startdate = startdate.replace(day=1)
enddate = enddate.replace(day=1)

# keep track of the series
dates = []

# create series by year
dates_years = []
current_year = startdate.year
while startdate <= enddate:
    
    # if the current year is not equal to the value of startdate.year
    if startdate.year != current_year:
        
        # update current year
        current_year = startdate.year
        
        # add the dates_year to dates
        dates.append(dates_years)
        
        # empty dates_years
        dates_years = []
        
    # store the date in current year
    dates_years.append(startdate.strftime("%b-%y"))
    
    # add a month
    startdate += relativedelta(months=1)
    
else:
    # add the last part
    if len(dates_years) > 0:
        dates.append(dates_years)

result: dates

[['Oct-14', 'Nov-14', 'Dec-14'],
 ['Jan-15',
  'Feb-15',
  'Mar-15',
  'Apr-15',
  'May-15',
  'Jun-15',
  'Jul-15',
  'Aug-15',
  'Sep-15',
  'Oct-15',
  'Nov-15',
  'Dec-15'],
 ['Jan-16']]
Dieter
  • 2,499
  • 1
  • 23
  • 41
0

You can do this via pandas:

import numpy as np
import pandas as pd
import datetime
from dateutil.relativedelta import relativedelta

startdate = "2014-10-10"  # input start date
enddate = "2016-01-07" 

## optionally - end date should be 1 + month, but date_range does also accept string-values
# cast the dates
startdate = datetime.date.fromisoformat(startdate)
enddate = datetime.date.fromisoformat(enddate) + relativedelta(months=1) # add 1 month

# convert to a data frame
dtr = pd.date_range(start=startdate, end=enddate, freq="M")

result

DatetimeIndex(['2014-10-31', '2014-11-30', '2014-12-31', '2015-01-31',
               '2015-02-28', '2015-03-31', '2015-04-30', '2015-05-31',
               '2015-06-30', '2015-07-31', '2015-08-31', '2015-09-30',
               '2015-10-31', '2015-11-30', '2015-12-31', '2016-01-31'],
              dtype='datetime64[ns]', freq='M')

step 2:

df = pd.DataFrame(dtr, columns=["dates"])
df['year'] = df.dates.dt.year

# add the result
df['output'] = [x.strftime("%b-%y") for x in df.dates]

result

    dates       year    output
0   2014-10-31  2014    Oct-14
1   2014-11-30  2014    Nov-14
2   2014-12-31  2014    Dec-14
3   2015-01-31  2015    Jan-15
4   2015-02-28  2015    Feb-15
5   2015-03-31  2015    Mar-15
6   2015-04-30  2015    Apr-15
7   2015-05-31  2015    May-15
8   2015-06-30  2015    Jun-15
9   2015-07-31  2015    Jul-15
10  2015-08-31  2015    Aug-15
11  2015-09-30  2015    Sep-15
12  2015-10-31  2015    Oct-15
13  2015-11-30  2015    Nov-15
14  2015-12-31  2015    Dec-15
15  2016-01-31  2016    Jan-16

step 3

group by year, and add dates into a list:

[list(output) for year, output in df.groupby('year').output]
result
[['Oct-14', 'Nov-14', 'Dec-14'],
 ['Jan-15',
  'Feb-15',
  'Mar-15',
  'Apr-15',
  'May-15',
  'Jun-15',
  'Jul-15',
  'Aug-15',
  'Sep-15',
  'Oct-15',
  'Nov-15',
  'Dec-15'],
 ['Jan-16']]
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Dieter
  • 2,499
  • 1
  • 23
  • 41