Business Hours (Hourly, 9 AM–5 PM Weekdays)
0 9-17 * * 1-5 0 0 9-17 ? * MON-FRI 0 9-17 * * 1-5 0 9-17 ? * MON-FRI * 0 0 9-17 * * MON-FRI 0 9-17 * * 1-5 Runs hourly at :00 from 09:00 to 17:00, Monday through Friday — 9 runs per weekday, none overnight or on weekends.
Use in your stack
# Hourly during business hours, US Eastern
CRON_TZ=America/New_York
0 9-17 * * 1-5 /usr/local/bin/business-hours-job.sh
{ "cron": "0 0 9-17 ? * MON-FRI", "timezone": "America/New_York" }
apiVersion: batch/v1
kind: CronJob
metadata:
name: business-hours-job
spec:
schedule: "0 9-17 * * 1-5"
timeZone: "America/New_York"
jobTemplate:
spec:
template:
spec:
containers:
- name: job
image: my-image:latest
restartPolicy: OnFailure
cron(0 9-17 ? * MON-FRI *)
@Scheduled(cron = "0 0 9-17 * * MON-FRI", zone = "America/New_York")
public void businessHours() { /* ... */ }
on:
schedule:
- cron: '0 9-17 * * 1-5' # hourly 09:00-17:00 UTC, Mon-Fri
Next runs
Pick a timezone to see when this expression fires next.
Next 10 runs
- 012026-08-19T15:00:00.000Z
- 022026-08-19T16:00:00.000Z
- 032026-08-19T17:00:00.000Z
- 042026-08-20T09:00:00.000Z
- 052026-08-20T10:00:00.000Z
- 062026-08-20T11:00:00.000Z
- 072026-08-20T12:00:00.000Z
- 082026-08-20T13:00:00.000Z
- 092026-08-20T14:00:00.000Z
- 102026-08-20T15:00:00.000Z
Variations
Common use cases
- Polling or syncing only while the business is open.
- Sending notifications during working hours so they're seen.
- Refreshing dashboards during the workday.
- Rate-limited API calls confined to business hours.
Gotchas
- The `9-17` range in the hour field is inclusive of both ends — it fires at 9, 10, 11, …, 17 (9 AM through 5 PM), which is 9 firings.
- Day-of-week numbering: Unix uses `1-5` (Mon-Fri). Quartz uses `MON-FRI`. Use name form to avoid the off-by-one.
- Timezone matters most here — "business hours" is meaningless without a pinned local timezone.
- AWS EventBridge: `0 9-17 ? * MON-FRI *`.
0 9-17 * * 1-5 is the business-hours schedule — hourly during the workday, silent overnight and on weekends. The inclusive hour range and the mandatory timezone pin are the two things to get right. Combine the range with a minute step (*/30) for sub-hourly business-hours cadence.
Frequently asked questions
What does `0 9-17 * * 1-5` mean?
Minute `0`, hour `9-17` (a range — 9 AM through 5 PM inclusive), day-of-month `*` (any), month `*` (any), day-of-week `1-5` (Monday through Friday). So the job fires at the top of every hour from 9 AM to 5 PM on weekdays — 9 times per weekday.
Does `9-17` include 5 PM?
Yes. Cron ranges are inclusive of both endpoints, so `9-17` fires at 9, 10, 11, 12, 13, 14, 15, 16, and 17 — that's 9 AM through 5 PM, nine firings. If you want to stop at 4 PM, use `9-16` (eight firings).
How do I run every 30 minutes during business hours instead of hourly?
Add a step to the minute field: `*/30 9-17 * * 1-5` fires at :00 and :30 of every hour from 9 AM to 5 PM on weekdays. `*/15 9-17 * * 1-5` fires every 15 minutes.
Why is the timezone so important here?
"Business hours" is defined entirely by local time — 9 AM in one timezone is the middle of the night in another. Always pin the timezone (`CRON_TZ`, `spec.timeZone`, or Spring's `zone`). On UTC-only schedulers like EventBridge and GitHub Actions, offset the hour range to match your target timezone.
More hours schedules
Other patterns on the same cadence — or browse every schedule.