1

Given a '%Y-%m' (e.g. 2022-03), what's a good way to get a list of the last days of its previous N (e.g. 5) months with desired results:

['2021-10-31', '2021-11-30', '2021-12-31', '2022-01-31', '2022-02-28']
Chris
  • 26,361
  • 5
  • 21
  • 42
Rock
  • 2,827
  • 8
  • 35
  • 47
  • 4
    Make a sequence of 1st days, `2022-03-01, 2022-04-01`, ... and subtract one day from them. `datetime.date`, `datetime.datetime` and `datetime.timedelta` are relevant modules in the standard libraries. – Kota Mori Oct 04 '22 at 05:56
  • Cool. Sounds doable. My brain was stuck with generating the last days using something like: `[str(k)+'-'+str(m)+'-'+str(calendar.monthrange(k, m)[1]) for k in range(2022, 2023) for m in range(1, 13)]` which over-complicates it. – Rock Oct 04 '22 at 06:00

2 Answers2

1

As mentioned in comments, you can use a list comprehension to generate a list of previous month starts, then subtract one day from each of them.

def previous_month_ends(date, months):
  year, month, day = [int(x) for x in date.split('-')]
  d = datetime.date(year, month, day)
  t = datetime.timedelta(1)
  s = datetime.date(year, month, 1)
  return [(x - t).strftime('%Y-%m-%d')
          for m in range(months - 1, -1, -1)
          for x in (datetime.date(s.year, s.month - m, s.day) if s.month > m else \
                    datetime.date(s.year - 1, s.month - (m - 12), s.day),)]

You'll want to do some math to ensure you handle the previous dates going into the previous year(s). The above will need to be modified to handle lartge values for months.

Chris
  • 26,361
  • 5
  • 21
  • 42
0

I figured Pandas already has Month End (M) freq in its builtin date_range function:

>>> end = datetime.strptime('2022-03', '%Y-%m')
>>> start = end - pd.DateOffset(months=5)
>>> pd.date_range(start, end, freq='M')
DatetimeIndex(['2021-10-31', '2021-11-30', '2021-12-31', '2022-01-31', '2022-02-28'], dtype='datetime64[ns]', freq=None)
Rock
  • 2,827
  • 8
  • 35
  • 47