Developer guide

Cron Every Day Except Holidays: Skipping Dates in Crontab

“Every day, but not on holidays” sounds like one cron line — it is not. Cron can't express a “not on July 4” rule at all. The reliable pattern is a thin wrapper script: cron still fires daily, the wrapper checks a holiday blocklist (or a calendar library), and exits silently on holiday dates. Here is that pattern for US holidays, Israel holidays, and a no-date-math business-day shortcut.

Benjamin Rotshtein

Written by Benjamin Rotshtein

Updated

Can cron skip holidays or specific dates?

No — cron has no calendar awareness, so it cannot know a date is a holiday. The standard solution is a wrapper script that checks a blocklist of dates (US, Israel or your own) and exits early on a match, while the crontab line stays a plain daily schedule. This guide shows that script plus a no-math business-day alternative.

Can cron skip holidays?
Not natively. You keep the daily cron line and let a wrapper script decide whether today is a holiday.
Simplest robust pattern?
A date blocklist file the wrapper checks against $(date +%F).
What about Israel / Hebrew-calendar holidays?
Use a library such as Python's hdate or the holidays package, since those dates change every Gregorian year.

Why cron cannot express “except holidays”

The five fields — minute, hour, day of month, month, day of week — are pure arithmetic. They can match “every day at 9” with 0 9 * * * but there is no field for “national calendar”. Any holiday logic has to live outside the crontab, in the code cron runs.

The wrapper script pattern

Change the crontab line to call a wrapper instead of the real job:

0 9 * * * /opt/scripts/skip-holidays.sh /opt/scripts/real-job.sh

The wrapper compares today against a plain-text blocklist and exits early on a match:

#!/usr/bin/env bash
# skip-holidays.sh — run <command> unless today is on the blocklist
set -euo pipefail

TODAY=$(date +%F)
BLOCKLIST="${1:?usage: skip-holidays.sh <cmd...>}"

if grep -qx "$TODAY" /etc/skip-dates.txt; then
  echo "Holiday: $TODAY — skipping"
  exit 0
fi

exec "$@"

The blocklist is one date per line:

# /etc/skip-dates.txt
2026-01-01
2026-07-04
2026-12-25

grep -qx forces a whole-line match, so partial dates can't accidentally match. This one file is your whole holiday calendar.

US holidays: fixed dates plus a moving-day library

Some US holidays are fixed and belong in the blocklist:

DateHoliday
2026-01-01New Year's Day
2026-06-19Juneteenth
2026-07-04Independence Day
2026-12-25Christmas Day

The moving holidays — Thanksgiving (4th Thursday of November), Memorial Day (last Monday of May) — are painful by hand. Let a library own them:

#!/usr/bin/env python3
# skip-us-holidays.py — exit 0 (skip) on US federal holidays
import sys
from datetime import date
import holidays

if date.today() in holidays.US():
    sys.exit(0)
sys.exit(1)   # not a holiday — caller should run the job

Wire it into cron with the exit-code logic inverted: the real job runs only when the wrapper returns non-zero. See the cron + Python guide for scheduling wrappers like this reliably.

Israel and Hebrew-calendar holidays

Israel holidays are the hard case because they follow the Hebrew calendar and shift every Gregorian year — a blocklist is unmaintainable. Use a converter library and skip the Israeli weekend (Friday) too:

#!/usr/bin/env python3
# skip-il-holidays.py — exit 0 on Israel holidays and the weekend
import sys
from datetime import date
import hdate

today = date.today()
if today.weekday() >= 4:            # Thu 3, Fri 4, Sat 5
    sys.exit(0)
if hdate.HDate(today).get_holiday():
    sys.exit(0)
sys.exit(1)

hdate.HDate(today).get_holiday() returns the holiday name when today is one — including Rosh Hashanah, Yom Kippur and the fasts — without you tracking a single date.

The “Friday approach” for business days

If weekends are your only hard rule, skip date logic entirely: run the job on Friday and let it cover the period through the weekend.

0 17 * * 5 /opt/scripts/weekly-cover.sh

The job runs once, every Friday, and processes the whole weekend window. To also honor one or two named holidays inside that window, combine it with the blocklist wrapper from above. Check the biweekly cron guide if your “every N weeks” needs go beyond holidays.

Generate a valid expression

Nail the daily or weekly schedule part with the Cron Generator — it produces the exact 5-field string and previews the next 5 runs, so the only date logic left to you is the holiday wrapper.

Frequently asked questions

Can cron skip holidays natively?

No. The 5-field cron format can only express time and weekday patterns — there is no 'except holidays' or 'except date X' syntax. You must wrap the job: keep cron firing daily and let a wrapper script decide whether today is a holiday and exit early if it is.

How do I skip specific dates in crontab?

Point the daily cron line at a wrapper script instead of the real job. The wrapper reads a plain-text list of dates, compares it against today's date, and exits with code 0 without doing any work on holiday dates. The actual job runs only when today is not on the list.

How do I skip US federal holidays?

Maintain a fixed-date list for the stable holidays (Jan 1, Jul 4, Dec 25, ...) and compute the moving ones such as Thanksgiving and Memorial Day in the wrapper — most libraries like Python's holidays package already encode them, so you simply check holidays.US() with today's date.

How do I skip Jewish or Israel holidays?

Jewish holidays follow the Hebrew calendar, so fixed dates are impossible. Use a library that converts the Hebrew calendar to Gregorian dates (Python's hdate or the holidays package with the Israel country code) and skip whenever today resolves to a holiday — with Sunday excluded as the Israeli weekend.

What is the Friday approach for business days?

If you only need to avoid weekends and you accept a single holiday pattern per week, run the job on Friday and have it cover the whole period until the next run. Combine it with the blocklist to also skip the one or two holiday dates inside that window.

If a holiday run is skipped, does cron retry it later?

No. When the wrapper exits early, the job is simply not executed that day — cron does not queue or retry skipped runs. If you need the work to happen anyway, schedule a second wrapper that runs on the next business day to make up for the missed execution.

Related guides