pythonpandasdatetimeperiod

Find all specified periods that fit into a certain date range


Suppose I have a certain defined range of dates, e.g. 2022-12-25 to 2023-02-05. I want to find all fully closed periods (specified by the user) that fit into this date range. For example, if the user specifies months and decades, the method should return

Another example would be finding all fully closed seasons (DJF, MMA, JJA, SON) and years in 2021-12-31 to 2023-02-28, which should result in

Is there a way to find this in pandas easily without many if/else conditions?


Solution

  • In case someone has the same issue this is the solution I found. It is not super clean but it seems to work.

    Basically for the monthly, seasonal and yearly cycle it is relatively easy to do as you can specify the frequency directly when creating the date range, so for example, starting from the seasonal frequency:

    season_start = pd.date_range(start='2022-12-25',
                  end='2024-02-05',
                  freq='QS-MAR')
    season_end = (season_start - pd.to_timedelta('1 day'))
    
    season_start[:-1].strftime('%Y-%m-%d'), season_end[1:].strftime('%Y-%m-%d')
    

    which gives

    ['2023-03-01', '2023-06-01', '2023-09-01']
    ['2023-05-31', '2023-08-31', '2023-11-30']
    

    You can apply exactly the same code for monthly and yearly frequency by using freq=MS and freq=YS, respectively.

    For the decade it's little bit more difficult but this seems to work

    daterange = pd.date_range(start='2023-02-05',
                  end='2023-04-01',
                  freq='D')
    
    daterange = daterange[daterange.day.isin([1, 11, 21])]
    
    daterange_end = (daterange - pd.to_timedelta('1 day'))
    
    daterange[:-1].strftime('%Y-%m-%d'), daterange_end[1:].strftime('%Y-%m-%d')
    

    which gives

    ['2023-02-11', '2023-02-21', '2023-03-01', '2023-03-11', '2023-03-21']
    ['2023-02-20', '2023-02-28', '2023-03-10', '2023-03-20', '2023-03-31']