Get (year,month) for the last X months

后端 未结 7 697
死守一世寂寞
死守一世寂寞 2020-12-10 05:06

I got a very simple thing to to in python: I need a list of tuples (year,month) for the last x months starting (and including) from today. So, for x=10 and toda

相关标签:
7条回答
  • 2020-12-10 05:32

    if you want to do it without datetime libraries, you can convert to months since year 0 and then convert back

    end_year = 2014
    end_month = 5
    start_year = 2013
    start_month = 7
    
    print list = [(a/12,a % 12+1) for a in range(12*end_year+end_month-1,12*start_year+start_month-2,-1)]
    

    python 3 (// instead of /):

    list = [(a//12,a % 12+1) for a in range(12*end_year+end_month-1,12*start_year+start_month-2,-1)]
    print(list)
    

    [(2014, 5), (2014, 4), (2014, 3), (2014, 2), (2014, 1), (2013, 12), (2013, 11), (2013, 10), (2013, 9), (2013, 8), (2013, 7)]

    0 讨论(0)
  • 2020-12-10 05:34

    If you create a function to do the date maths, it gets almost as nice as your original implementation:

    def next_month(this_year, this_month):
      if this_month == 0: 
        return (this_year - 1, 12)
      else:
        return (this_year, this_month - 1)
    
    this_month = datetime.date.today().month()
    this_year = datetime.date.today().year()
    for m in range(0, 10):
      yield (this_year, this_month)
      this_year, this_month = next_month(this_year, this_month)
    
    0 讨论(0)
  • 2020-12-10 05:34

    Or you can define a function to get the last month, and then print the months ( it's a bit rudimentary)

    def last_month(year_month):#format YYYY-MM
        aux = year_month.split('-')
        m = int(aux[1])
        y = int(aux[0])
    
        if m-1 == 0:
            return str(y-1)+"-12"
        else:
            return str(y)+"-"+str(m-1)
    
    def print_last_month(ran, year_month= str(datetime.datetime.today().year)+'-'+str(datetime.datetime.today().month)):
        i = 1 
        if ran != 10:
            print( last_month(year_month) )
            print_last_month(i+1, year_month= last_month(year_month))
    
    0 讨论(0)
  • 2020-12-10 05:35

    Neatest would be to use integer division (//) and modulus (%) functions, representing the month by the number of months since year 0:

    months = year * 12 + month - 1 # Months since year 0 minus 1
    tuples = [((months - i) // 12, (months - i) % 12 + 1) for i in range(10)]
    

    The - 1 in the months expression is required to get the correct answer when we add 1 to the result of the modulus function later to get 1-indexing (i.e. months go from 1 to 12 rather than 0 to 11).

    Or you might want to create a generator:

    def year_month_tuples(year, month):
        months = year * 12 + month - 1 # -1 to reflect 1-indexing
        while True:
            yield (months // 12, months % 12 + 1) # +1 to reflect 1-indexing
            months -= 1 # next time we want the previous month
    

    Which could be used as:

    >>> tuples = year_month_tuples(2011, 7)
    >>> [tuples.next() for i in range(10)]
    
    0 讨论(0)
  • 2020-12-10 05:37

    Update: Adding a timedelta version anyway, as it looks prettier :)

    def get_years_months(start_date, months):
        for i in range(months):
            yield (start_date.year, start_date.month)
            start_date -= datetime.timedelta(days=calendar.monthrange(start_date.year, start_date.month)[1])
    

    You don't need to work with timedelta since you only need year and month, which is fixed.

    def get_years_months(my_date, num_months):
        cur_month = my_date.month
        cur_year = my_date.year
    
        result = []
        for i in range(num_months):
            if cur_month == 0:
                cur_month = 12
                cur_year -= 1
            result.append((cur_year, cur_month))
            cur_month -= 1
    
        return result
    
    if __name__ == "__main__":
        import datetime
        result = get_years_months(datetime.date.today(), 10)
        print result
    
    0 讨论(0)
  • 2020-12-10 05:38

    Using relativedelta ...

    import datetime
    from dateutil.relativedelta import relativedelta
    
    def get_last_months(start_date, months):
        for i in range(months):
            yield (start_date.year,start_date.month)
            start_date += relativedelta(months = -1)
    
    >>> X = 10       
    >>> [i for i in get_last_months(datetime.datetime.today(), X)]
    >>> [(2013, 2), (2013, 1), (2012, 12), (2012, 11), (2012, 10), (2012, 9), (2012, 8), (2012, 7), (2012, 6), (2012, 5)]
    
    0 讨论(0)
提交回复
热议问题