How to Calculate Business Days (and the 7 Bugs Everyone Ships)
"Add 3 business days" sounds trivial. In production it is a reliable source of off-by-one bugs, angry customers and late fees. Here's what a correct implementation has to handle.
1. Define "business day" per system
A business day is a day that is not a weekend day and not a holiday for the system that does the work. ACH runs on the Federal Reserve calendar, euro payments on TARGET2, UK Direct Debits on Bacs, equities on the exchange calendar. "Public holidays in country X" is the wrong source for all of them.
2. Weekends are not always Saturday–Sunday
Saudi Arabia, Israel and several others use Friday–Saturday weekends; the UAE moved to Saturday–Sunday in 2022. Instant-payment rails like FedNow have no weekend at all.
3. Observed holidays move
When a holiday lands on a weekend, it may be observed on Friday, Monday, or not at all, depending on the calendar. The Fed and the NYSE disagree on Saturday holidays; the UK uses "substitute days" that can push Christmas and Boxing Day to the 27th and 28th.
4. Be explicit about inclusive vs exclusive
When adding N business days, don't count the start date: Friday + 1 business day = Monday. When counting the business days between two dates, pick a convention (Bankday uses start-exclusive, end-inclusive) and document it.
5. Time zones decide what "today" is
At 9 p.m. in California it is already tomorrow in London. Determine the date in the time zone of the system you're modelling (America/New_York for the Fed), not the server's UTC clock.
6. Roll conventions for due dates
When a computed date lands on a holiday: following moves forward, preceding moves back, modified following moves forward unless that crosses into the next month (common for month-end payments and coupons).
7. Holiday data goes stale
New holidays get created (Juneteenth, 2021), closures announced with days of notice (NYSE, January 2025), and governments move dates. A holiday list pinned in your repository will silently drift.
The one-line version
curl "https://bankday.jacklehoff4866.workers.dev/v1/business-days/add?calendar=us-fed&date=2026-12-23&days=3" \ -H "Authorization: Bearer $BANKDAY_KEY"
curl "https://bankday.jacklehoff4866.workers.dev/v1/business-days/roll?calendar=eu-target2&date=2026-05-31&convention=modified_following" \ -H "Authorization: Bearer $BANKDAY_KEY"
Language-specific versions: Python · JavaScript · Excel
Get a free API key
1,000 requests/month free. No credit card. Your key appears instantly.