cronuru
Pattern

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
  1. 012026-07-03T17:00:00.000Z
  2. 022026-07-06T09:00:00.000Z
  3. 032026-07-06T10:00:00.000Z
  4. 042026-07-06T11:00:00.000Z
  5. 052026-07-06T12:00:00.000Z
  6. 062026-07-06T13:00:00.000Z
  7. 072026-07-06T14:00:00.000Z
  8. 082026-07-06T15:00:00.000Z
  9. 092026-07-06T16:00:00.000Z
  10. 102026-07-06T17: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.

Browse all cron patterns

Every schedule Cronuru documents, with its expression and code snippets for six dialects.