nas
nas

Reputation: 2417

How to display all the months between given two dates?

I am trying to generate list of months between two dates. For Example:

startDate = '2016-1-31'
endDate = '2017-3-26'

It should result as:

datetime.date(2016, 1, 31)
datetime.date(2016, 2, 28)
and so on....

I am trying like this

startDate = '2016-1-28'
endDate = '2017-3-26'

start = date(*map(int, startDate.split('-')))
end = date(*map(int, endDate.split('-')))

week = start
dateData = []

while week <= end:
    dateData.append(week)
    week = week + datetime.timedelta(weeks=4)

pprint(dateData)

This gives result as:

[datetime.date(2016, 1, 31),
 datetime.date(2016, 2, 28),
 datetime.date(2016, 3, 27),
 datetime.date(2016, 4, 24),
 datetime.date(2016, 5, 22),
 datetime.date(2016, 6, 19),
 datetime.date(2016, 7, 17),
 datetime.date(2016, 8, 14),
 datetime.date(2016, 9, 11),
 datetime.date(2016, 10, 9),
 datetime.date(2016, 11, 6),
 datetime.date(2016, 12, 4),
 datetime.date(2017, 1, 1),
 datetime.date(2017, 1, 29),
 datetime.date(2017, 2, 26),
 datetime.date(2017, 3, 26)]

Here "2016, 12" & "2017, 1" is repeating twice. Can anybody help me solve this problem.

Upvotes: 9

Views: 16464

Answers (3)

asmatrk
asmatrk

Reputation: 257

You can also use only pandas in one line:

import pandas as pd
pd.date_range('2018-01', '2020-05', freq='M')

The output will be:

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

Upvotes: 9

shad0w_wa1k3r
shad0w_wa1k3r

Reputation: 13372

You could use the dateutil extension's relativedelta method like below -

from datetime import datetime
from dateutil.relativedelta import relativedelta

startDate = '2016-1-28'
endDate = '2017-3-26'

cur_date = start = datetime.strptime(startDate, '%Y-%m-%d').date()
end = datetime.strptime(endDate, '%Y-%m-%d').date()

while cur_date < end:
    print(cur_date)
    cur_date += relativedelta(months=1)

Following is the output

2016-01-28
2016-02-28
2016-03-28
2016-04-28
2016-05-28
2016-06-28
2016-07-28
2016-08-28
2016-09-28
2016-10-28
2016-11-28
2016-12-28
2017-01-28
2017-02-28

Upvotes: 13

NineTails
NineTails

Reputation: 550

I'm not privileged enough to comment yet, but your program is doing exactly as it is told. 4 weeks equals 28 days. The difference between 1st Jan and 29th Jan (2017) is 28 days; therefore you are getting the same month twice.

You might want to redefine what you are trying to solve. If however, you do want to solve just for the months of the years between the two dates, your code will need some expanding.

  1. You need to create a loop to iterate over the years and months.
  2. You will need a condition for the start year and end year to ensure you begin at the start month and finish at the end month.

Here is a working example, it includes the start and end dates in the list as well. I hope it helps:

import datetime

startDate = '2016-1-28'
endDate = '2017-3-26'

start = datetime.date(*map(int, startDate.split('-')))
end = datetime.date(*map(int, endDate.split('-')))

week = start
dateData = []

dateData.append(start)

rangeYear = (end.year - start.year)

for i in range(rangeYear + 1):
    if i == 0:
        for j in range(1,13-start.month):
            date = datetime.date(start.year, start.month+j, 1)
            dateData.append(date)
    elif (i > 0) & (i < rangeYear):
        for j in range(1,12):
            date = datetime.date(start.year+i, j, 1)
            dateData.append(date)
    elif i == rangeYear:
        for j in range(1,end.month):
            date = datetime.date(start.year+i, j, 1)
            dateData.append(date)

dateData.append(end)

Upvotes: 1

Related Questions