There are times when you will need to calculate yesterday’s date in a UNIX shell script to run some date sensitive cron jobs. There are currently no standard command line tools in UNIX to perform such date arithmetic.
Writing a program in C or Java to perform such date arithmetic is actually an overkill. If you have the GNU date command installed, you can get the date quite easily by running date as follows:
1 2 |
$ date -d "-1 day" Sat Jul 4 16:30:08 MPST 2009 |
GNU date is available in Linux distributions. It’s not available by default in commercial UNIX distributions such as AIX or Solaris. To calculate yesterday’s date for such platforms, you can use the following script instead. Save the following script to a file called yesterday, chmod to 755 and copy it to a directory in your PATH.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#!/bin/sh # # Script to calculate yesterday's date with custom output date format # # Author: ibrahim - stackpointer.io # # default output format defaultof="%Y%m%d" # check for input format, else use default format, # refer to 'man date' for help on format # script only supports %Y %m %d at the moment of=$defaultof [ $# -eq 1 ] && of="$1" # get today's date eval "`date +'y=%Y m=%m d=%d'`" # subtract 1 day d=`expr $d - 1` if [ $d -eq 0 ]; then # if day is 0, subtract month by 1 m=`expr $m - 1` if [ $m -eq 0 ]; then # if month is 0, subtract year and set month to 12 m=12 y=`expr $y - 1` fi # set day depending on value of month d=31 if [ $m -eq 4 ] || [ $m -eq 6 ] || [ $m -eq 9 ] || [ $m -eq 11 ] ; then d=30 fi # check for leap year if [ $m -eq 2 ]; then d=28 leap1=`expr $y % 4` leap2=`expr $y % 100` leap3=`expr $y % 400` if [ $leap1 -eq 0 ] ; then if [ $leap2 -gt 0 ] || [ $leap3 -eq 0 ] ; then d=29 fi fi fi fi #Solaris date does not accept -d #date -d "$y-$m-$d" +"$of" eval "y=`expr $y + 0` m=`expr $m + 0` d=`expr $d + 0`" eval "y=`printf "%04d" $y` m=`printf "%02d" $m` d=`printf "%02d" $d`" echo "$of" | sed -e "s/%Y/$y/" -e s/%m"/$m/" -e "s/%d/$d/" |
Below are some examples on how the script can be called:
1 2 3 4 5 6 7 8 9 10 11 |
$ date Sun Jul 5 17:13:12 MPST 2009 $ yesterday 20090704 $ yesterday "prefix %Y-%m-%d postfix" prefix 2009-07-04 postfix $ yesterday "%Y-%m-%d" 2009-07-04 |
Update (9-Nov-2010): Script updated to run on Solaris platforms
Update (7-Aug-2011): Script updated to prevent printf function from interpreting certain numbers as octal