After digging through cron documentation and testing various configurations, I've found that weekly cron jobs trigger based on system time, specifically when both of these conditions are met:
- The minute/hour specified in the cron expression matches current time
- The system's week counter has rolled over (typically Sunday midnight)
Most Unix-like systems consider the week to start on Sunday at 00:00 (midnight). This means a weekly cron job like:
0 0 * * 0 /path/to/script.sh
would execute at midnight between Saturday and Sunday. However, there's an important distinction:
@weekly /path/to/script.sh
The @weekly
shortcut specifically means "run once a week at midnight on Sunday morning".
Different cron implementations may handle this slightly differently:
System | Weekly Start Time |
---|---|
Vixie cron (most Linux) | Sunday 00:00 |
FreeBSD cron | Sunday 00:00 |
MacOS cron | Sunday 00:00 |
Solaris cron | Sunday 00:00 (configurable) |
Here are some common weekly cron patterns with explanations:
# Run every Sunday at 3:15 AM 15 3 * * 0 /usr/bin/backup.sh # Alternative using @weekly syntax (midnight Sunday) @weekly /usr/local/bin/weekly_report.sh # Wednesday at noon (not actually weekly, just showing the day field) 0 12 * * 3 /scripts/midweek_check.sh
Remember that the day-of-week field (0-6 or SUN-SAT) uses 0 or 7 for Sunday in most implementations.
To test when your weekly cron will actually run:
# For systems with systemd: systemctl list-timers --all # Alternative method using cron debug: sudo tail -f /var/log/cron
The exact log location may vary between /var/log/syslog
, /var/log/cron
, or journalctl output depending on your system.
In Unix/Linux cron, weekly jobs (specified as 0 0 * * 0
) start at midnight between Saturday and Sunday (Sunday 00:00). This follows the traditional Unix convention where Sunday is considered day 0 in the week.
The cron daemon calculates weekly jobs based on the system's locale settings. Here's how it works internally:
struct tm {
int tm_sec; /* seconds (0-60) */
int tm_min; /* minutes (0-59) */
int tm_hour; /* hours (0-23) */
int tm_mday; /* day of the month (1-31) */
int tm_mon; /* month (0-11) */
int tm_year; /* year - 1900 */
int tm_wday; /* day of the week (0-6, Sunday = 0) */
int tm_yday; /* day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* daylight saving time */
};
While Sunday is default in most systems, some locales consider Monday as the first day. You can check your system's week start:
# Check system locale settings
locale
# Output may include:
LC_TIME="en_US.UTF-8" # Typically Sunday-first
LC_TIME="ru_RU.UTF-8" # Typically Monday-first
Here are some common weekly cron patterns:
# Run every Sunday at midnight
0 0 * * 0 /path/to/script.sh
# Run every Monday at 3:15 AM (for Monday-first systems)
15 3 * * 1 /path/to/script.sh
# Alternative using @weekly (always Sunday)
@weekly /path/to/script.sh
For consistent behavior across systems:
# Explicitly set timezone in crontab
CRON_TZ=UTC
0 0 * * 0 /path/to/script.sh # Will always run at Sunday 00:00 UTC