Summary: Cron Question

From: Marco Greene <>
Date: Thu May 08 2003 - 13:05:34 EDT
Thanks to all who replied.

My original post:

I need to run a cron job on the last day of the month,

every month.

I can do it with 3 lines in crontab, one for each

month having 31, 30 and 28 days (and 29 every 4th year).

There were two solutions.

One was to run the script on the first of each month.

The other one was to write a script that should

determine the last day of the month.

Here are the replies for the second solution:

There are two ways I can think of that you can do this in a script.

If you have the shutils package from, then

just do a :

if [ ! "`/usr/local/bin/date -d tomorrow +%d`" = "01 ]; then





Or, w/o shutils,

if [ ! "`TZ=GMT-24;date +%d`" = "01" ]; then





Then in your cron, you can just run the script everyday.


Ray Pasetes


You can alway get this by calculating backward:

end of March will be 4/1 - 1 day

Zaigui Wang


That wouldn't work so well on the months with 29 days, would it? :-)

> Is there any other way to do it? Thanks in

FAQ. Try a google search for:

"last day of the month" crontab

Of course, you'll find a lot of wrong answers and half-right answers

along with the correct ones.

Best solution if you can is to install GNU date. GNU date understands

exactly how to do "tomorrow" and "yesterday" and "one week ago", etc.

and understands that in the context of daylight time switches in your

timezone, etc. Then your crontab looks like:

0 23 * * * if [ `/usr/local/bin/date +%d -d tomorrow` = 01 ] ; then

; fi

If you can't have GNU date, then ignore the people who say:

0 23 * * * if [ `env TZ=$TZ-24 date +%d` = 01 ] ; then your_command ; fi

Because $TZ-24 doesn't do what they think it does. Remember what I

said about GNU date understanding daylight time and timezones? $TZ-24

doesn't understand *any* of that and will give you the wrong answer

unless you carefully tailor the "-24" number. Hint: -24 won't work

right unless you live in England, and even then, it won't work right if

you run it within two hours of the daylight saving switch time.

So if you can't have GNU date, you really need to do something

like run a perl script *every* day, and the script decides whether

to run or not...

#!/usr/bin/perl -w

#sec min hour mday mon year wday yday isdst

(undef,undef,undef,$dom,undef,undef,undef,undef,undef) =


# $dom is day-of-month for 24 hours in the future

if ($dom == 1) {

# Do what you want



Jay Lessert


you could run a script the 28th-31st and at the start of the

script check to see if tomorow is "1" then you know today is the end of

whatever month it is.

Hope this helps.


tom=`env TZ=$TZ-24 date +%d`

if [[ $tom = = "01" ]];then


your job







Derek Olsen


Michael Gleibman


I simply run a script every morning and check within the script

to see if it is the last day or not and either exit or run the script....


lastday=`cal | egrep '^[2,3]' | tail -1 | awk '{print $NF}'`

today=`date +"%d"`

if [ "$today" = "$lastday" ]; then




Mark McManus


As you have discovered, there is no way to tell 'cron' to run a

command only on the last day of the month.

An alternative work-around to yours, and one that fits on a single

line is this: have 'cron' run the command on days 28-31. On each

month, it will run from 1-4 times depending on the number of days

in the month, so modify your script (or write a wrapper for your

program/script) that checks the date and simply exits if this isn't

the last day of the current month.

Your crontab entry would look something like this:

0 1 28-31 * * <command>

And in your script (or wrapper) you could do something like this:


TOMORROW=`TZ=EST-19EDT date +%d`

if [ "${TOMORROW}" != "01" ] ;then

# This is NOT the last day of the month, so exit

exit 1


# If we get here, today is the last day of the month



(The "TZ=EST-19EDT" is a little trick to get 'date' to give you

"tomorrow", assuming you are in the US Eastern time zone, which

appears to be the case from the headers of your message. What you

really put is your current offset from GMT (UTC) minus 24 (EST

offset is 5, 5-24= -19). For me, in the US Central zone, I would use

"TZ=CST-18CDT" (6-24=-18). Valid values for this trick range from -99

to 99, approximately 4 days plus or minus.)

Hope this helps!


Mark Scarborough


Probably the simplest way of doing this is to have a script run every
28-31 of each month and, within the script, exit if that day isn't the
last day of the month. This can be done by checking to see whether 24
hours in the future is still the same month. Try something like:


#! /bin/sh

current_month=`date +%m`

tomorrow_month=`TZ=GMT-20 date +%m`

if [ $current_month -ne $tomorrow_month ]






The above is appropriate for Eastern Daylight Time (EDT is 4 hours offset
from GMT ... 24-4=20 -> use "GMT-20" as the timezone.) This would work
for both EST and EDT if the script was not run within one hour of
midnight. If you want to run your script at, say, 10PM, you just have to
check to see if 12 hours from now is the next month (that way, you don't
care if daylight saving time is in effect or not.)


Tim Pointing


Thank you again to all of you,



MSN 8 with e-mail virus protection service: 2 months FREE*
sunmanagers mailing list
Received on Thu May 8 13:05:28 2003

This archive was generated by hypermail 2.1.8 : Thu Mar 03 2016 - 06:43:13 EST