Date manipulation

In my shell script I take date as a input parameter from command line in the format "21 Oct 2011" which would be

 date +'%d %b %Y'

Now i need to do two things here.
1) Validate the date entered by user
2) Calculate yesterday's date from the input. So in this case it should be: "20 Oct 2011"

Can someone please help me do this? I know I could do this quickly in perl or some other scripting lang, but here i only have bash shell scripting option

Thanks in advance.

Hi davidtd,

Try:

$ cat script.pl
use warnings;
use strict;
use POSIX;
use Time::Local;

@ARGV == 1 or die qq[Usage: perl $0 "date"\n];

my %TAB_MONTH = ( 
        jan     =>      0,
        feb     =>      1,
        mar     =>      2,
        apr     =>      3,
        may     =>      4,
        jun     =>      5,
        jul     =>      6,
        aug     =>      7,
        sep     =>      8,
        oct     =>      9,
        nov     =>      10,
        dec     =>      11
);

my ($mday, $month, $year) = split /\s+/, $ARGV[0];

timelocal( 0, 0, 0, $mday, $TAB_MONTH{ lc $month } || -1 , $year - 1900) or die qq[ERROR: Incorrect format of date\n];
my $utc_date = POSIX::mktime( 0, 0, 0, $mday, $TAB_MONTH{ lc $month }, $year - 1900 );
my $errno = POSIX::errno();
$utc_date -= (60 * 60 * 24);

(undef, undef, undef, $mday, $month, $year) = localtime $utc_date;
my %rTAB_MONTH = reverse %TAB_MONTH;
printf qq[%d %s %d\n], $mday, $rTAB_MONTH{ $month }, $year + 1900;
$ perl script.pl "21 Oct 2011"
20 oct 2011
$ perl script.pl "46 Oct 2011"
Day '46' out of range 1..31 at script.pl line 25
 $ perl script.pl "21 Gbd 2011"
Month '-1' out of range 0..11 at script.pl line 25

Regards,
Birei

Thanks, but this looks little complicated for my script... I think i will drop the validation requirement but can some one help me with Calculating yesterday's date from the input. So in this case how can i get previous days date in this case: "20 Oct 2011"

maybe you can have a look at post #9 of :

$ uname -sr
SunOS 5.9
$ date +'%d %b %Y'
22 Oct 2011
$ TZ=CST+24 date +'%d %b %Y'
21 Oct 2011
$

In some other country whose timezone differs from GMT, you should take into account the offset a reliable calculation could be something like

# -- calculate time using GMT -- 
Uday=`TZ=GMT date +%d`
Uhr=`TZ=GMT date +%H`
Lday=`date +%d`
Lhr=`date +%H`   
if [ $Lday = $Uday ]
then Offset=`expr $Uhr - $Lhr` 
else Offset=`expr $Uhr + 24 - $Lhr` 
fi   
Diff=`expr 24 + $Offset` echo -n "yesterday was " TZ=GMT+$Diff date +%Y-%m-%d   
Diff=`expr 24 - $Offset` echo -n "tomorrow will be " TZ=GMT-$Diff date +%Y-%m-%d

Thanks all for some good tips. But here is how i resolved my problem.
My issue was, date is in the format like: "24 Oct 2011" which is "date +'%d %b %Y'" in shell script, and I wanted to find the previous day which should be : "23 Oct 2011". Below is the code I executed to get this result.

input="24 Oct 2011"
temp1=$(echo $input | awk '{print $1}')
temp2=$(expr $temp1 - 1)
temp3=$(echo $input | awk '{print $2,$3}')
preDay=$temp2" "$temp3

Resulting output is:

23 Oct 2011

ok, and what about input="1 Mar 2011" or input="1 Jan 2012" ?

Thats a good question... To be honest... I have not thought anything about that scenario but will have to put in some more checks to account for those scenario. Will have to think through it more...but yes if you have any more robust and simpler solution please let me know.

don't reinvent the wheel - check the FAQs.