All Docs
FeaturesagentOS Direct DebitUpdated March 12, 2026

UK Bank Holiday & BACS Working Day Calendar

UK Bank Holiday & BACS Working Day Calendar

The Direct Debit service includes a built-in UK bank holiday calendar and a BACS working day utility. Together these ensure that all collection dates, receipt dates, and mandate schedules are accurate and compliant with the BACS processing cycle.

Why This Matters

BACS Direct Debit operates on UK banking working days only — weekends and bank holidays are not processing days. Getting this wrong leads to:

  • Collections submitted on non-processing days being rejected or delayed.
  • Tenants seeing incorrect "funds leave your account" or "funds received" dates on the mandate form.
  • Month-end mandates silently shifting to the wrong calendar date.

This utility is the single source of truth for all date arithmetic in the service.


Bank Holiday Data

A bank_holidays table is seeded from the official UK Government bank holidays API and kept current automatically. Only the England & Wales division is used, as this is the jurisdiction applicable to BACS Direct Debit processing.


Working Day Utility

All date calculations are performed server-side via a dedicated utility module. The following functions are available internally and underpin all scheduling, mandate form date display, and collection submission logic.

isBACSWorkingDay(date)

Returns true if the supplied date is a valid BACS working day.

A date is a BACS working day if it is:

  • A Monday through Friday, and
  • Not a UK bank holiday (England & Wales).
isBACSWorkingDay('2025-12-25') // false — Christmas Day
isBACSWorkingDay('2025-12-26') // false — Boxing Day
isBACSWorkingDay('2025-12-29') // true

addWorkingDays(date, n)

Returns the date that is n BACS working days after the supplied date, skipping weekends and bank holidays.

addWorkingDays('2025-04-17', 3) // skips Good Friday, Easter Monday

subtractWorkingDays(date, n)

Returns the date that is n BACS working days before the supplied date, skipping weekends and bank holidays in reverse.


collectionDateToReceiptDate(collectionDate)

Resolves a collection date to its expected receipt date. The default offset is T+3 BACS working days, reflecting the standard BACS credit clearing cycle.

This is used on the mandate form to show tenants two distinct dates:

LabelMeaning
Collection dateWhen funds leave the tenant's bank account
Receipt dateWhen the agent expects to receive the funds
collectionDateToReceiptDate('2025-06-02') // '2025-06-05' (T+3 working days)

Edge Case Handling

February 29 / 30 / 31

Monthly mandates can be set to collect on a specific day of the month (e.g. the 31st). When the scheduled day does not exist in a given month (most commonly February, but also shorter months for the 29th–31st), the date is rolled forward to the 1st of the following month before BACS working day resolution is applied.

Scheduled dayMonthResolved calendar date
29February (non-leap)1 March
30February (non-leap)1 March
31February1 March
31April1 May

Sunday-to-Monday Adjustment

If a resolved collection date falls on a Sunday, it is advanced to the following Monday before BACS working day checks are applied. This ensures the date is never a non-processing day prior to further working day calculations.


Relationship to Other Features

  • Mandate Form — The payment details step uses collectionDateToReceiptDate to display the collection date and receipt date pair to the tenant before they confirm.
  • Collection Scheduling — The collection submission job uses isBACSWorkingDay and addWorkingDays to determine valid submission windows.
  • Alert Thresholds — Upcoming collection forecasting relies on the working day calendar to project amounts due within a given period.