Documentation
Business Days JQL adds four date functions to Jira's JQL that count in working days instead of calendar days, skipping weekends and the holidays you list.
Stuck right now? Two shortcuts before you read any further:
Cannot find the app after installing it? It has no panel and no button — it lives in
the JQL box and on one page under Apps. See *Where to find it after installing*, next.
Need a person? Email support@maxpetrov.pp.ua. What to put in that email is under
*Getting help* at the foot of this page.
This app has no in-context surface. It does not add a panel to a work item, a button to a screen, or an item to any menu you are already looking at. If you have just installed it and nothing on your screens looks different, nothing is wrong. There are exactly two places it shows up:
1. In the JQL box. Switch Jira's search from *Basic* to *JQL* and start typing one of the four function names. One character is enough for Jira's own autocomplete to offer it. Nothing has to be enabled per project.
`` duedate <= businessDaysFromNow(10) created >= businessDaysAgo(5) ``
2. On the app's own page, under Apps. Open Apps in Jira's top navigation and choose Business Days JQL. That page is where the working week, the time zone and the holiday list are set, and it is the only screen the app has. Its sections are labelled A · Working week, B · Time zone, C · Holidays, D · Try it, E · Stored answers.
If neither of those shows anything, the app is not installed on this site, or the site's licence for it is not active — the app's page states which, in words, at the top.
Function | Returns |
|---|---|
| the date |
| the date |
| alias of |
| alias of |
The two pairs are aliases of each other, so whichever name your team reaches for first is the one that works. Each takes a second, optional calendar argument.
Capitalisation does not matter, and a name Jira does not recognise is refused out loud. businessDaysAgo(5), businessdaysago(5) and BUSINESSDAYSAGO(5) are the same query and return the same work items. A name that is genuinely misspelled is a different matter: Jira refuses the whole query before it runs and tells you so, naming the function it could not find. So if a search ran and simply came back with fewer rows than you expected, the function name is not what went wrong — it was accepted.
Each function returns a date, so it goes on the right-hand side of a comparison against any date field — duedate, created, updated, resolutiondate, or a custom date field — and all six comparison operators work: =, !=, >, >=, <, <=.
They work in ad-hoc search and in saved filters, which means they also work anywhere a saved filter is used: boards, dashboards gadgets, and subscriptions.
`` duedate <= businessDaysFromNow(10) ORDER BY duedate ASC created >= businessDaysAgo(5) AND statusCategory != Done updated < workingDaysAgo(3) AND assignee = currentUser() project = OPS AND duedate = businessDaysFromNow(1) ``
Everything is on the app's page under Apps → Business Days JQL.
A · Working week. Tick the days that count as working days. The default is Monday to Friday. A Sunday-to-Thursday week is set by ticking those five and clearing the other two.
B · Time zone. Which day counts as "today". Jira reads the dates these functions produce in your site's time zone, so a site that is not on UTC needs this set or every answer is a day out for part of each day. Enter an IANA name such as Europe/Kiev, or a fixed offset such as +03:00. If the runtime cannot resolve a named zone the page says so and asks for a fixed offset instead.
C · Holidays. One date per line, as YYYY-MM-DD, up to 2000 dates. A holiday that falls on a working day pushes every answer one working day further out. Lines that are not valid dates are not silently dropped: the page lists each rejected line back to you with the line number and the reason.
D · Try it. The page computes each function against the calendar you have saved and shows the date it currently resolves to, so you can check the configuration without running a search.
Press Save calendar and the app immediately recomputes the answers it has stored, so a search run straight afterwards reflects the new calendar.
One working week, one time zone and one holiday list cover the whole site. Teams in different countries share one answer, so a site spanning two countries gets one team's day boundary wrong. This is the app's main limitation. There is no per-project and no per-team calendar, and the time zone in section B is what decides where each team's day starts.
A date function's answer moves as the calendar moves: businessDaysAgo(5) means a different date tomorrow than it does today. The app therefore keeps its answers up to date on its own, without anybody opening the page.
Section E · Stored answers shows what it holds: the function, the clause it was used in, the date currently stored, the date freshly computed, and a current or stale lozenge for whether they agree. Refresh now runs the same work immediately.
A single refresh run stops at a fixed limit rather than running unbounded. Each run resumes where the previous one stopped and wraps round at the end, so every stored answer is reached in turn. When a run does not reach everything, the page says how many rows it did not reach.
Some answers cannot be refreshed at all — most often a date function used against a field that is not a date, which Jira refuses to store a value for. Those are listed as unrefreshable and are skipped from then on rather than retried on every run.
A bad argument returns no results rather than wrong ones, and in Jira's issue search the app names the fault in its own error banner. The REST search API receives the empty result without that message, and an automation rule or filter subscription may do the same, so the app's page under Apps states the rule too.
Which of the two you get depends on where the query runs. The issue search box and the REST search API were both driven against a live site; the other callers below are named as unmeasured:
In the issue search box, a bad argument produces a red JQL error carrying the
app's own sentence. businessDaysAgo("abc") and a missing argument both give *"Business Days JQL needs a whole number of days, not "abc". Put the number inside the brackets, e.g. businessDaysAgo(5)."* — the text you typed is echoed back to you. businessDaysAgo(99999) gives *"Business Days JQL accepts 0 to 3650 days; 99999 is beyond that."*
Through the REST search API, the same queries come back as an ordinary empty result
set with no message at all: Jira does not pass the app's sentence on to that caller. Other callers, such as a filter subscription or an automation rule, have not been measured and may do the same, which is why the rule is repeated here and on the app's own page under Apps.
Returning nothing is deliberate — it is better to show nothing than to show a wrong list — but on the silent path the query itself cannot tell you what went wrong.
Check, in this order:
1. The argument. It must be a non-negative whole number. 2. The field. The function returns a date, so the left-hand side must be a date field. 3. The working week, on the app's page, section A. A calendar with no working days ticked has no answer to give, and the page says so under D · Try it. 4. The time zone, section B. A site that is not on UTC with the zone left at UTC is a day out for part of each day. 5. The licence. If the site's licence for the app is not active, the page says so at the top and searches return nothing.
The app does not read or sync Jira's own Time Tracking working-days setting. Set the working week on the app's page instead. The two settings are independent and Jira does not expose the Time Tracking one to a Forge app.
No per-project or per-team calendar, and no per-user calendar.
No business-hours or part-day arithmetic — the unit is a whole working day.
No holiday-calendar import and no per-country preset; holidays are typed in.
No panel, glance or button on a work item. The config page is the only screen.
No SLA or breach reporting, and no reading of Jira's own Time Tracking configuration.
The app runs entirely on Atlassian infrastructure, calls no external service, declares no remote hostnames, and stores no personal data. It reads only its own data: its Jira scopes are read:app-data:jira and write:app-data:jira, which do not grant access to work items, projects or users. Full detail is in the privacy policy linked from the Marketplace listing.
Email support@maxpetrov.pp.ua. Include the exact JQL you ran, which of the four functions it used, and what the app's own page under Apps shows in sections A, B and C. If a query returned nothing you did not expect, the argument is the first thing to check: a bad argument returns no results rather than wrong ones, and in Jira's issue search the app names the fault in its own error banner. The REST search API receives the empty result without that message, and an automation rule or filter subscription may do the same, so the app's page under Apps states the rule too.
Last updated: 13 September 2026.