17

How do I set up a cron job which runs on Monday of the week when there is a 3rd Thursday?

Example, in March the 3rd Thursday is on the 20th, so the job needs to run on 17th which is a Monday.

Similarly, in April the 3rd Thursday is on 17th, so the job will needs to run on 14th.

virolino
  • 141
darkage
  • 271

2 Answers2

23

The first Thursday of a month is between the 1st and the 7th day of the month (inclusive). The second Thursday is between 8th and 14th, the third Thursday is between 15th and 21st.

The Monday in the week of the third Thursday is exactly three days before the third Thursday, so between 12th and 18th day (inclusive).

You need your cron job to run on Monday between 12th and 18th day of each month.

A job with initial fields 30 8 12-18 * MON is not right for this because it would run each day from 12th to 18th and on every Monday outside of the range. This is a known quirk of cron. Answers to the linked question provide methods to deal with the quirk. There are methods that require some logic in the script cron is going to run; and there are methods that put all the logic inside crontab. Choose whatever fits your needs.

E.g. the method from this answer tailored to your case will look like this in your crontab:

30 8 */100,12-18 * MON /path/to/executable

Notes:

  • There are various implementations of cron. It may be some methods don't work with some implementations.

  • Some implementations of cron provide a system-wide crontab that requires an extra field. See this question. If you choose to use the system-wide crontab then build your crontab entry accordingly.

12

If you're running a reasonably modern Linux system, I'd suggest considering systemd timers. We can use a similar construct to Kamil's answer, minus the quirks of cron:

/etc/systemd/system/foo.service:

[Service]
Type=oneshot
ExecStart=/path/to/binary args

/etc/systemd/system/foo.timer (by default activates the matching .service):

[Timer]
OnCalendar=Mon *-*-12..18 12:00:00

Then systemctl enable --now foo.timer to enable (for startup) and start (counting now) the timer.

The other advantage of this approach is you get full service control, including any dependencies (what else needs to be started/available first?), error/failure handling, etc. of a service.

The expected dates this will run can be verified with a command like systemd-analyze --iterations=3 calendar "Mon *-*-12..18 12:00:00".

Bob
  • 63,170