2

I have two yyyymm values that will be input by a user:

yyyymm_1 = '201406'
yyyymm_2 = '201501'

I want to be able to iterate through this range in increasing month order:

for yyyy and mm in the range of yyyymm_1 to yyyymm_2
    my_function( yyyy, mm )

How can this be done in python?


Update:

Ideally, the solution should be as simple as possible without requiring external libraries. I'm not looking for a generic date manipulation solution, but a solution to answer the specific question I have asked above.

I had seen lots of generic solutions before posting my question. However, being a python noob, couldn't see how to adapt them to my question:

On that note, the other questions linked to from this page are much more generic. If you are looking to generate a range of yyyymm values, I urge you to look at the selected answer on this page.

Community
  • 1
  • 1
Chris Snow
  • 23,813
  • 35
  • 144
  • 309
  • 1
    What did you try? By the way, a [question similar to this one](https://stackoverflow.com/q/28035042/2476444) popped up less than 2 days ago. Did you search for similar questions based on the keywords? – Oliver W. Jan 20 '15 at 10:05
  • http://stackoverflow.com/a/1060352/1673391 – Grijesh Chauhan Jan 20 '15 at 10:08
  • This question and the selected answer is clearly different to the other question and answers. This question is specifically asking how to generate a set of yyyy and mm values from yyyy mm date ranges. I could not find any questions that are asking the same as this question. – Chris Snow Jan 20 '15 at 21:28
  • They look pretty much the same to me, Chris. In what way would you say they differ? – Lightness Races in Orbit Jan 20 '15 at 22:01
  • There are different level of abstraction. I am working with yyyymm values whereas the other questions mostly are at the level of yyyymmdd. Some of the questions allow you to provide an interval value, e.g. days, but this doesn't translate easily when you have months having different numbers of days. One solution uses datetime.timedelta that doesn't seem to support months: https://docs.python.org/2/library/datetime.html#datetime.datetime – Chris Snow Jan 20 '15 at 22:13
  • I personally think this is a more specific variant of the question this is marked as a duplicate of, but since answers can no longer be added to this question, I've added my answer to that one: https://stackoverflow.com/a/50957962/4909785 – Dan Coates Jun 20 '18 at 22:32

2 Answers2

5

Here's another rather simple variant, without even using datetime. Just split the date, calculate the 'total month', and iterate.

def to_month(yyyymm):
    y, m = int(yyyymm[:4]), int(yyyymm[4:])
    return y * 12 + m

def iter_months(start, end):
    for month in range(to_month(start), to_month(end) + 1):
        y, m = divmod(month-1, 12)  # ugly fix to compensate
        yield y, m + 1              # for 12 % 12 == 0

for y, m in iter_months('201406', '201501'):
    print y, m

Output:

2014 6
2014 7
...
2014 12
2015 1

For output in the same yyyymm format, use print("%d%02d" % (y, m)).

tobias_k
  • 81,265
  • 12
  • 120
  • 179
3

You can do this using the builtin datetime module and the third party package dateutil.

The code first converts your strings to datetime.datetime objects using datetime.datetime.strptime. It then uses the relativedelta function from dateutil to create a period of one month that can be added to your datetimes.

Within the while loop you can either work with the datetime objects directly, or construct the month and year as strings using strftime, I've shown an example of both in print functions.

import datetime as dt
from dateutil.relativedelta import relativedelta

yyyymm_1 = '201406'
yyyymm_2 = '201501'

MONTH = relativedelta(months=+1)

fmt = '%Y%m'
date_1 = dt.datetime.strptime(yyyymm_1, fmt).date()
date_2 = dt.datetime.strptime(yyyymm_2, fmt).date()

d = date_1

while d <= date_2:
    print(d)
    print(d.strftime('%Y'), d.strftime('%m'))

    d += MONTH
Ffisegydd
  • 51,807
  • 15
  • 147
  • 125