Generating (StartDateOfMonth, EndDateofMonth) for every month within date range
Question: I want to generate a list of (StartDateOfMonth, EndDateOfMonth) values for a
specified date range. e.x. time range: 2011-09-11, 2013-04-24, the list should
be :

    
    
    [('2011-9-11', '2011-9-30'), ('2011-10-01', '2011-10-31'), ('2011-11-01', '2011-11-30'), ('2011-12-01', '2011-12-31'), ('2012-1-01', '2012-1-31'), ('2012-2-01', '2012-2-29'), ('2012-3-01', '2012-3-31'), ('2012-4-01', '2012-4-30'), ('2012-5-01', '2012-5-31'), ('2012-6-01', '2012-6-30'), ('2012-7-01', '2012-7-31'), ('2012-8-01', '2012-8-31'), ('2012-9-01', '2012-9-30'), ('2012-10-01', '2012-10-31'), ('2012-11-01', '2012-11-30'), ('2012-12-01', '2012-12-31'), ('2013-1-01', '2013-1-31'), ('2013-2-01', '2013-2-28'), ('2013-3-01', '2013-3-31'), ('2013-4-01', '2013-4-24')]
    

I have come up with a somewhat ugly looking code. This is partly because of my
lack of list compherension and other capibilities of Python. The code is:

    
    
    def getMonthRanges(startDate, endDate):
        dateRange = []
    
        allYears= [eachYear for eachYear in range(startDate.year, endDate.year+1)]
        allMonths= [eachMonth for eachMonth in range(1, 13)]
    
        for eachYear in allYears:
            for eachMonth in allMonths:
                if eachYear == startDate.year:
                    if eachMonth == startDate.month:
                       startOfMonth = str(eachYear)+'-'+str(eachMonth) + '-'+str(startDate.day)
                       endOfMonth =   str(eachYear)+ '-'+str(eachMonth) + '-'+str(calendar.monthrange(eachYear, eachMonth)[1])
                       dateRange.append((startOfMonth, endOfMonth))
                    elif eachMonth > startDate.month:
                       startOfMonth = str(eachYear)+ '-'+str(eachMonth) + '-01'
                       endOfMonth = str(eachYear)+'-'+str(eachMonth)+ '-'+ str(calendar.monthrange(eachYear, eachMonth)[1])
                       dateRange.append((startOfMonth, endOfMonth))
                    else:
                        continue
                if eachYear == endDate.year:
                    if eachMonth == endDate.month:
                        startOfMonth = str(eachYear)+'-'+str(eachMonth) + '-01'
                        endOfMonth =   str(eachYear)+ '-'+str(eachMonth) + '-'+str(endDate.day)
                        dateRange.append((startOfMonth, endOfMonth))
                        break
                    elif eachMonth < endDate.month:
                        startOfMonth = str(eachYear)+ '-'+str(eachMonth) + '-01'
                        endOfMonth = str(eachYear)+'-'+str(eachMonth)+ '-'+ str(calendar.monthrange(eachYear, eachMonth)[1])
                        dateRange.append((startOfMonth, endOfMonth))
                elif eachYear > startDate.year and eachYear < endDate.year:
                    startOfMonth = str(eachYear)+ '-'+str(eachMonth) + '-01'
                    endOfMonth = str(eachYear)+'-'+str(eachMonth)+ '-'+ str(calendar.monthrange(eachYear, eachMonth)[1])
                    dateRange.append((startOfMonth, endOfMonth))
    
        return dateRange
    

Requesting feedback from other developers if this code can be
condensed/improved?


Answer: Here's a way to do it using only the [_datetime_
module](http://docs.python.org/2.7/library/datetime.html#module-datetime):

    
    
    >>> from datetime import date, timedelta
    >>> from pprint import pprint
    
    >>> def next_month(x):
            'Advance the first of the month, wrapping the year if necessary'
            if x.month < 12:
                return x.replace(month=x.month+1, day=1)
            return x.replace(year=x.year+1, month=1)
    
    >>> def getMonthRanges(startDate, endDate):
            result = []
            first = startDate
            while first < endDate:
                nm = next_month(first)
                last = min(endDate, nm - timedelta(days=1))
                result.append([str(first), str(last)])
                first = nm
            return result
    
    >>> pprint(getMonthRanges(date(2011, 9, 11), date(2013, 4, 24)))
    [['2011-09-11', '2011-09-30'],
     ['2011-10-01', '2011-10-31'],
     ['2011-11-01', '2011-11-30'],
     ['2011-12-01', '2011-12-31'],
     ['2012-01-01', '2012-01-31'],
     ['2012-02-01', '2012-02-29'],
     ['2012-03-01', '2012-03-31'],
     ['2012-04-01', '2012-04-30'],
     ['2012-05-01', '2012-05-31'],
     ['2012-06-01', '2012-06-30'],
     ['2012-07-01', '2012-07-31'],
     ['2012-08-01', '2012-08-31'],
     ['2012-09-01', '2012-09-30'],
     ['2012-10-01', '2012-10-31'],
     ['2012-11-01', '2012-11-30'],
     ['2012-12-01', '2012-12-31'],
     ['2013-01-01', '2013-01-31'],
     ['2013-02-01', '2013-02-28'],
     ['2013-03-01', '2013-03-31'],
     ['2013-04-01', '2013-04-24']]
    

