Search code examples
pythonpandasdatecalendar

Getting current passed business dates and total business days from custom calendar


I have a pandas CustomBusinessDay calendar defined as below:

from pandas.tseries.offsets import CustomBusinessDay
from pandas.tseries.holiday import Holiday, AbstractHolidayCalendar

class feriados(AbstractHolidayCalendar):
    rules = [
        Holiday('New Years Day', month=1, day=1, year=2022),
        Holiday('May Day', month=5, day=1, year=2022),
        Holiday('14/04', month=4, day=17, year=2022),
        Holiday('Constitution Day', month=4, day=21, year=2022),
        Holiday('Pentecost Sunday', month=5, day=1, year=2022),
        Holiday('Corpus Christi', month=9, day=7, year=2022),
        Holiday('Assumption of the Blessed Virgin Mary', month=10, day=12, year=2022),
        Holiday('All Saints Day', month=11, day=2,  year=2022),
        Holiday('Independence Day', month=11, day=15, year=2022),
        Holiday('Christmas Day', month=12, day=25, year=2022),
        
        
        Holiday('New Years Day', month=1, day=1, year=2023),
        Holiday('Carnival', month=2, day=20, year=2023),
        Holiday('Carnival', month=2, day=21, year=2023),
        Holiday('Passion of Christ', month=4, day=7, year=2023),
        Holiday('TakeTooths', month=4, day=21, year=2023),
        Holiday('Labour Day', month=5, day=1, year=2023),
        Holiday('Corpus Christi', month=6, day=8, year=2023),
        Holiday('Independence Day', month=9, day=7, year=2023),
        Holiday('Nossa Sr.a Aparecida - Padroeira do Brasil', month=10, day=12, year=2023),
        Holiday('Finados', month=11, day=2, year=2023),
        Holiday('Proclamação da República', month=11, day=15, year=2023),
        Holiday('Christmas Day', month=12, day=25, year=2023),]


BUSINESS_DAY = CustomBusinessDay(
    calendar=feriados(),
    weekmask='Mon Tue Wed Thu Fri')

I want to calculate how many business days have already passed and how many total business days we have in the current month.

Can anybody help me with these?


Solution

  • From BUSINESS_DAY, you can use pd.bdate_range to get what you expect:

    from pandas.tseries.offsets import MonthBegin, MonthEnd
    
    today = pd.Timestamp.now().normalize()
    bdays = pd.bdate_range(today - MonthBegin(), today + MonthEnd(), freq='C',
                           weekmask=BUSINESS_DAY.weekmask, 
                           holidays=BUSINESS_DAY.holidays)
    

    Output:

    >>> bdays
    DatetimeIndex(['2023-08-01', '2023-08-02', '2023-08-03', '2023-08-04',
                   '2023-08-07', '2023-08-08', '2023-08-09', '2023-08-10',
                   '2023-08-11', '2023-08-14', '2023-08-15', '2023-08-16',
                   '2023-08-17', '2023-08-18', '2023-08-21', '2023-08-22',
                   '2023-08-23', '2023-08-24', '2023-08-25', '2023-08-28',
                   '2023-08-29', '2023-08-30', '2023-08-31'],
                  dtype='datetime64[ns]', freq='C')
    
    # 9 business days are passed
    >>> (bdays == today).argmax()
    9
    
    # 23 business days in the current month
    >>> len(bdays)
    23