The 0 0 * * 1-5 Expression
The cron expression 0 0 * * 1-5 fires at midnight, Monday through Friday. Field breakdown: minute (0), hour (0), day of month (*), month (*), day of week (1-5). Midnight weekdays is a common base. Most teams adjust the hour field to fit their actual need. The core concept here is the 1-5 range in the day of week field, which is what makes this page worth understanding regardless of what time you set.
The 1-5 Range in the Day of Week Field
Day of week in POSIX cron is the fifth field, and it uses the following numbering:
| Number | Day |
|---|---|
| 0 | Sunday |
| 1 | Monday |
| 2 | Tuesday |
| 3 | Wednesday |
| 4 | Thursday |
| 5 | Friday |
| 6 | Saturday |
| 7 | Sunday (alias) |
The range 1-5 matches Monday through Friday. Saturday (6) and Sunday (0 or 7) are excluded. This is the mechanism behind every “run only on business days” cron expression you will encounter.
MON-FRI Alias
In Vixie cron and most modern implementations, three letter abbreviations work in the day of week field:
0 0 * * MON-FRI # identical to 0 0 * * 1-5
0 0 * * MON,WED,FRI # Monday, Wednesday, Friday only
0 0 * * TUE,THU # Tuesday and Thursday
Named aliases improve readability in shared crontabs. They work in cronie (the default on RHEL/CentOS/Fedora), Vixie cron (Debian/Ubuntu), and most managed cloud schedulers. If portability across minimal or embedded cron implementations matters, use numerics.
Why Weekday Only Schedules Exist
The primary reason is human availability. Automated systems that notify, alert, or deploy should account for whether anyone is around to respond. Common cases:
Business process automation
Invoice generation, report distribution, and data reconciliation jobs that feed into workflows humans act on daily don’t need to run over weekends when the output will sit unread until Monday.
Deployments and alerts
Many teams restrict production deploys to weekdays so that an engineer is available to roll back if something goes wrong. An on call alert at 2 AM Saturday is less useful if the team is unavailable until Monday.
Resource cost
If a job triggers downstream processing, API calls, or external services, running it five days a week instead of seven saves roughly 28% in operational costs on that component.
SLA aligned processing
Jobs tied to business SLAs (payment processing windows, end of day reconciliation, business hour reporting) are inherently weekday only because the underlying SLA is.
Holidays Are Not Handled by Cron
Cron has no awareness of public holidays. A job scheduled with 1-5 will run on Christmas Day and New Year’s Day if they fall on a weekday. If that is a problem, the solution is at the application layer:
#!/bin/bash
# Check holiday list before executing
HOLIDAY_FILE="/etc/holidays.txt"
TODAY=$(date +%Y-%m-%d)
if grep -q "$TODAY" "$HOLIDAY_FILE"; then
echo "Skipping: $TODAY is a holiday"
exit 0
fi
# Run the actual job
/opt/jobs/business-report
Maintain the holiday file as part of your infrastructure configuration. Some teams generate it annually from a calendar API (like the Google Calendar API or a country specific public holiday API) and deploy it alongside their crontabs.
Common Weekday Patterns
The 0 0 * * 1-5 base is almost always adjusted. These are the patterns that actually appear in production crontabs:
Daily job at a specific business time:
0 9 * * 1-5 # 9 AM weekdays, morning job before standup
0 6 * * 1-5 # 6 AM weekdays, prep data before business hours start
0 18 * * 1-5 # 6 PM weekdays, end-of-day processing
Interval within business hours:
*/15 9-17 * * 1-5 # every 15 min, 9 AM to 5 PM, weekdays
*/30 8-18 * * 1-5 # every 30 min during extended business hours
0 * 9-17 * * 1-5 # top of every hour during business hours (note: this is a 6-field expression for some implementations)
Multiple fixed times on weekdays:
0 9,12,17 * * 1-5 # 9 AM, noon, and 5 PM weekdays
0 8,16 * * 1-5 # twice daily at shift boundaries
Monday only or Friday only:
0 0 * * 1 # midnight Monday, weekly kickoff job
0 23 * * 5 # 11 PM Friday, end-of-week cleanup before weekend
Interaction Between day of month and day of week
An important cron edge case: if both the day of month field and the day of week field are explicitly set (neither is *), cron runs the job on the union of both constraints, not the intersection.
0 0 15 * 1-5 # runs on the 15th of any month AND on every weekday
This does not mean “weekdays that fall on the 15th.” It means “every weekday plus the 15th of each month.” If you want to restrict execution to a specific combination, you need script level logic, not a more complex cron expression.
With 0 0 * * 1-5, the day of month is *, so this edge case does not apply.
Verifying the Schedule
from croniter import croniter
from datetime import datetime
cron = croniter("0 0 * * 1-5", datetime.now())
for _ in range(7):
print(cron.get_next(datetime))
Run through 7 iterations and you will see the schedule skips Saturday and Sunday. Use the cron builder on this page to see the next 10 run times interactively.