Here is a ksh script to calculate the previous date of the first argument, tested on Solaris 10.
#!/bin/ksh
sep=""
today=$(date '+%Y%m%d')
today=${1:-today}
ty=`echo $today|cut -b1-4` # today year
tm=`echo $today|cut -b5-6` # today month
td=`echo $today|cut -b7-8` # today day
yy=0 # yesterday year
ym=0 # yesterday month
yd=0 # yesterday day
if [ td -gt 1 ];
then
# today is not first of month
let yy=ty # same year
let ym=tm # same month
let yd=td-1 # previous day
else
# today is first of month
if [ tm -gt 1 ];
then
# today is not first of year
let yy=ty # same year
let ym=tm-1 # previous month
if [ ym -eq 1 -o ym -eq 3 -o ym -eq 5 -o ym -eq 7 -o ym -eq 8 -o ym - eq 10 -o ym -eq 12 ];
then
let yd=31
fi
if [ ym -eq 4 -o ym -eq 6 -o ym -eq 9 -o ym -eq 11 ];
then
let yd=30
fi
if [ ym -eq 2 ];
then
# shit... :)
if [ ty%4 -eq 0 ];
then
if [ ty%100 -eq 0 ];
then
if [ ty%400 -eq 0 ];
then
#echo divisible by 4, by 100, by 400
leap=1
else
#echo divisible by 4, by 100, not by 400
leap=0
fi
else
#echo divisible by 4, not by 100
leap=1
fi
else
#echo not divisible by 4
leap=0 # not divisible by four
fi
let yd=28+leap
fi
else
# today is first of year
# yesterday was 31-12-yy
let yy=ty-1 # previous year
let ym=12
let yd=31
fi
fi
printf "%4d${sep}%02d${sep}%02d\n" $yy $ym $yd
Tests
bin$ for date in 20110902 20110901 20110812 20110801 20110301 20100301 20080301 21000301 20000301 20000101 ; do yesterday $date; done
20110901
20110831
20110811
20110731
20110228
20100228
20080229
21000228
20000229
19991231