Unix Tip: Is this the Last Day of the Month?
Send in your Unix questions today!
See additional Unix tips and tricks
One of the issues that has long irritated Unix users when setting up cron jobs is how to set up a job to run on the last day of the month. Unless one wants to set up a separate cron job for every month (and this still leaves the problem of leap years), it isn't at all straightforward how to attack this seemingly ordinary problem with an ordinary solution. However, there are some reliable ways to code around the problem. One long winded but workable way to determine the last day of any month in any year is to string together some well known Unix commands. The last day in the month of February next year, for example, could be extracted from the last non-blank line in the output of the calender command like this:
>; cal 2 2007 | grep -v "^$" | tail -1 | awk '{print $NF}'
28
Of course, that is a lot of work just to grab the last chunk of information from the output of the cal command. The grep -v command removes the last line of output if it happens to be blank and the awk command prints the last chunk of data on the line. In a script, you would do something like this:
month=`date +%m`
today=`date +%e`
year=`date +%Y
lastday=`cal $month $year | grep -v "^$" | tail -1 | awk '{print $NF}'`
if [ $today == $lastday ]; then
echo your code runs here
fi
The more popular methods of determining whether today is the last day of the month depend on, not determining what day the current month ends on, but on figuring out whether tomorrow is the 1st. For this kind of calculation, you might do something like this:
TZ=`date +%Z`-24 date +%d
In this command, we're fiddling with the timezone variable to calculate tomorrow's date. We are asking, in essence, in a (fictitious) timezone that is 24 hours ahead of the local timezone, what would today's date be? The answer is tomorrow. Cut and paste the command onto your command line and you should see something like this (if you run this on the 6th of the month):
>; TZ=`date +%Z`-24 date +%d 07
To use this logic in a script, you might do somemthing like this:
#!/bin/bash TZone=`date +%Z` if test `TZ=$TZone-24 date +%d` = 01; then echo your code runs here fi
NOTE: If your system responds "7" instead of "07" to the pasted command, change "01" to "1".
Another option is to use Perl's handy commands for working with time. Here's one example:
#!/usr/bin/perl
use POSIX;
@now = localtime (time);
++$now[3]; # increment date for tomorrow
if ((localtime (POSIX::mktime (@now)))[3] == 1) {
print "your code here\n";
}
exit 1;
In this script, we're storing the output of the localtime command into an array, incrementing the 4th element of the array (element 3 -- the day of the month) and asking whether the date is the first. The second localtime call is needed to interpret the incremented date. Simply incrementing the date field might give us 31 or even 32 -- not exactly what we are looking for.
Finally, here's some bash code that makes use of Perl to calculate whether tomorrow is in the same month as today -- an equally valid test as asking whether tomorrow is the 1st:
#!/bin/bash
todayMonth=`date +%m`
tomorrowMonth=`perl -e '@T=localtime(time+86400);printf("%02d",$T[4]+1)'`
if [ $tomorrowMonth != $todayMonth ]; then
echo your code here
fi
The key to this script is the number 86400 -- the number of seconds in a single day. When you add 86,400 seconds to today's date, you get tomorrow. After all, dates on Unix systems are stored as the number of seconds since the beginning of the Unix epoch.
 
ITworld.com
Essential JavaFX
Get started building rich Web apps quickly with an introduction to the power of JavaFX key features -- scene node graphs, nodes as components, the coordinate system, layout options, colors and gradients, custom classes with inheritance, animation, binding, and event handlers.Enter now!
The Nomadic Developer
Consulting can be hugely rewarding, but it's easy to fail if you are unprepared. To succeed, you need a mentor who knows the lay of the land. Aaron Erickson is your mentor, and this is your guidebook. Enter now!












