Why crontab uses OR when both day of month and day of week specified? Why crontab uses OR when both day of month and day of week specified? unix unix

Why crontab uses OR when both day of month and day of week specified?


Going back a step further from Vixie cron, the "wday OR mday" logic was present in System V cron, but not System III or anything earlier.

Before Paul Vixie wrote his cron replacement, BSD cron was like the SysIII-and-earlier cron. All 5 fields were ANDed. The post-4.4 BSDs adopted Vixie cron, making themselves more SysV-like.

So don't ask (blame) Vixie. He was just cloning SysV.

Why did SysV do that? I don't know but I'll try to provide some partial clues...

To try to understand what happened in SysV, it helps to look at the source (before - SysIII and after - SVr4) and also the documentation of the new behavior:

Note: the specification of days may be made by two fields (day of the month and day of the week). If both are specified as a list of elements, both are adhered to.

(Excerpt from SunOS 4.1.3 man page. It appears to be SysV-ish in this area. BSD cron never had this behavior before Paul Vixie wrote his replacement.)

"Both are adhered to" is a confusing substitute for a normal boolean expression using ANDs and ORs. It's still there in the OpenSolaris man page a couple of decades later:

The specification of days can be made by two fields (day of the month and day of the week). Both are adhered to if specified as a list of elements.

The SysV code is a complete rewrite. One of its features is that it sleeps for a long time when no jobs are due to run soon. (The older cron wakes up every minute and compares the current time to all job specifications.) A comment at the top of the calculation function (next_time) explains: NOTE: this routine is hard to understand.

It is indeed hard to understand. It is a "find next execution time for this crontab line" function, instead of a "decide whether the current time matches this crontab line" function, so it takes some effort to even figure out that the matching rule implicit in this function, when both mday and wday are non-*, is (month AND hour AND minute AND (mday OR wday)).

Based on that, combined with the way the documentation avoids explicitly telling us the boolean relationship between mday matching and wday matching, I'm going to guess that the person who wrote the new cron just wasn't thinking about it in those terms. They were thinking not about a combination of 5 booleans (corresponding directly to 5 fields in a struct tm), but about a set of 4 questions:

  1. Is it the correct month?
  2. Is it the correct day?
  3. Is it the correct hour?
  4. Is it the correct minute?

This leads naturally to the day comparisons being combined in their own way before ANDing everything else together. Maybe the SysV cron author just did what felt like the obvious thing at the time, without checking for compatibility with the old cron or pondering use cases like "first Saturday of every month".


Maybe this won't be a deep enough "why" to satisfy you - it certainly doesn't satisfy me - but a shallow answer is "because the standard says so".

Specifically, the POSIX standard dictates at http://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html that:

if either the month or day of month is specified as an element or list, and the day of week is also specified as an element or list, then any day matching either the month and day of month, or the day of week, shall be matched

(bolding mine).

I have no idea why this is what the standard requires. Interestingly, it seems like even Paul Vixie, who implemented Vixie Cron (the Cron implementation used on both Ubuntu and MacOS) doesn't know either; in cron.c there's this comment:

/* the dom/dow situation is odd.  '* * 1,15 * Sun' will run on the * first and fifteenth AND every Sunday;  '* * * * Sun' will run *only* * on Sundays;  '* * 1,15 * *' will run *only* the 1st and 15th.  this * is why we keep 'e->dow_star' and 'e->dom_star'.  yes, it's bizarre. * like many bizarre things, it's the standard. */

So, by the sounds of it, even the implementer of the Cron you're probably using doesn't know the answer to your question in any more depth than the non-explanation I give in the first paragraph of this answer.


I work on a Unix server that uses many scripts in the crontab. It is very convenient for us to be able to indicate specific dates on scripts that should run on a single day of the week. In my case, I can't see why I would run a scheduled script on a day of the week ONLY if it is on a 13th, taking your example.