SUMMARY: cron entry: nth day of every month?

From: Cohen, Andy (Andy.Cohen@cognex.com)
Date: Wed Apr 27 2005 - 17:24:53 EDT


SUMMARY
=======

Short answer: No, cron can not handle this with its own syntax. One
needs to add shell-logic either directly in the crontab entry or in the
shell script.

Long answer: A few different approaches but basically the same idea.
Either run it every Friday and check that the date is between the 15th
and the 21st of the month. Alternatively, run it every month between
the 15th and the 21st and check to see if it's a Friday.

=-=-=-=-

Maybe something like this would work:

0 0 15-21 * * (date | grep Fri > /dev/null) && command

I.e., the line gets executed every day at Midnight between the 15th and
21st but "command" only runs if the output of the "date" command
contains "Fri".

=-=-=-=-=-=-=-=-=-=-=-=-=-

I don't think there is any simple way of doing this with cron.

What I would suggest is rather than embedding the logic in each script
write one wrapper that take the date spec and runs/exec the actual
script if "today's" date is the one specified.
eg

03 07 * * 5 /scripts/ckdate -d 'third friday' -c /my/real/script

ckdate could be a shell or perl etc script.

Gnudate is quite good for this stuff
(grab the date routines if you want to write a C wrapper.) eg
         required_date=`gnudate +'%Y-%m-%d' -d 'third friday this month'`
         now=`gnudate +'%Y-%m-%d'`
         if [ "$now" = "$required_date" ] ; then
                 ...
         fi

=-=-=-=-=-=-=-=-=-=-

The answer is it is _not_ possible to control it only with crontab
scheduling options, but you _can_ control it entirely within crontab and
without modifying your script/program.

Here is one that I have that runs the 3rd Friday of every month:

----------------------------------------------------------------
1 18 15-21 * * [ `date +\%w` -eq 5 ] &&
/usr/local/bin/Atlas_full_backup > /nsr/logs/Atlas_full_`date
+\%Y-\%m-\%d`.out 2>&1
----------------------------------------------------------------

(all on one line, of course)

Here is what it does:

1 18 15-21 * * - runs the cron job at 6:01 PM on the 15th-21st of every
month

[ `date +\%w` -eq 5 ] && - checks if today is Friday and
continues if it
is, otherwise, the job ends without running anything else.

The rest is just the script execution command which sends all its output
to a date-named log file.

You could also do it the other way around, running the cron job _every_
Friday and then testing for a particular date range. Whatever. It
makes more sense to my brain this way. :-)

In case it isn't clear, this works because the 3rd occurrence of any
particular day can't occur before the 15th - because the first 2 weeks
of the month take up the first 14 days - nor can it occur after the 21st
- 'cause then you're into the 4th week.

=-=-=-=-=-=-=-=-=-=-=-

Unfortunately, cron does a logical 'or' with the date and day-of-week
fields, so what you want could be quite complicated. What I have done
in the past is write a 'wrapper' script that runs at the specified time
every Friday and checks for the current date being in the correct range.

   If it is, it falls through and executes the specified chunk of code.
  For example, the earliest day of the month that could be the third
Friday is the 15th and the last is the 21st. Your 'wrapper' would
contain something like:

#!/bin/ksh
TODAY=`date +%d`
if [ ${TODAY} -lt 15 -a ${TODAY} -gt 21 ]
then
     exit
fi
(commands to execute on the third friday)

This would be invoked via a cron entry something like:

1 0 * * 5 /path/to/wrapper

The job would run every Friday, but if the date was not between the 15th

and 21st (inclusive) it will just exit without running the 'payload'

=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Then a slight different approach:

How about 12 entries, one for each 3rd friday of each month?

ie 21st Jan, 18th Feb, 18th Mar, etc in 2005?

Two advantages - it's simple and you are forced to visit it at least
once a year for maintenance.

=-=-=-=-=-=-=-

Thanks to:
David Powell
Mark Scarborough
James Sainsbury
Jay Leafey
Paul A Sand

ORIGINAL QUESTION
=================
 
Hi,

I need to run a job on the 3rd Friday of every month. Is it possible to
control this with just crontab or do I need to run it every Friday and
inlude shell commands in the script that is being run to figure out if
it's the 3rd Friday?

Has anybody done something like this?

Thanks!

Andy



This archive was generated by hypermail 2.1.7 : Sat Apr 12 2008 - 10:50:18 EDT