Scripting issue

I am having a problem. which I have described below>>

I have to run a script with the format : <File_name><Start_date><End_date>

abcd.sh 19-JAN-2015 01-May-2014

problem is I need to compare these two dates and throw an error as start date must be less than or equal to end date.

But given that I am passing the dates as arguments I cant compare them. Someone please help me on this. It would be really helpful.

The tools available for processing dates and times vary considerably between operating systems and shells.

What operating system are you using?

What shell are you using?

1 Like

I am using bash shell
OS - Linux MXDNS 2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux

Hello Chandan_Bose,

Could you please try following as a first point and let me know if this helps you.

cat script.ksh
START_DATE=$1
END_DATE=$2;
if [[ -n $1 && -n $2 ]]
then
        awk -vstart_date="$START_DATE" -vend_date="$END_DATE" 'BEGIN{;num=split("JAN FEB MAR APR MAY JUN JULY AUG SEPT OCT NOV DEC", array," ");for(i=1;i<=num;i++){Q[array]=i};split(start_date, A,"-");split(end_date, B,"-");if(A[3] <= B[3] && Q[toupper(A[2])] <= Q[toupper(B[2])]){if((A[3] == B[3] && Q[toupper(A[2])] == Q[toupper(B[2])] && A[1] <= B[1]) || (A[3] == B[3] && Q[toupper(A[2])] < Q[toupper(B[2])]) || (A[3] < B[3] && Q[toupper(A[2])] < Q[toupper(B[2])])){print "start_date " start_date " seems to be less than " end_date " end_date."} else {print "Date is NOT in proper format."}} else {print "Date is NOT in proper format."}}'
else
        echo "One of the argument is seems to be missing while running the script."
fi

Examples of some runs as follows.

./script.ksh 19-MAY-2015 01-May-2015
Date is NOT in proper format.
AND
/script.ksh 19-MAY-2015 31-May-2015
start_date 19-MAY-2015 seems to be less than 31-May-2015 end_date.

It will compare the dates but it is not that intelligent enough if user has given wrong output like 32 days in May month etc(trusting user here :)). It will compare the dates and run the script.
EDIT: Adding a non-one liner form of solution here too.

START_DATE=$1
END_DATE=$2;
if [[ -n $1 && -n $2 ]]
then
        awk -vstart_date="$START_DATE" -vend_date="$END_DATE" 'BEGIN{
                                                                        num=split("JAN FEB MAR APR MAY JUN JULY AUG SEPT OCT NOV DEC", array," ");
                                                                        for(i=1;i<=num;i++){
                                                                                                Q[array]=i
                                                                                           };
                                                                        split(start_date, A,"-");
                                                                        split(end_date, B,"-");
        if(A[3] <= B[3] && Q[toupper(A[2])] <= Q[toupper(B[2])]){
        if((A[3] == B[3] && Q[toupper(A[2])] == Q[toupper(B[2])] && A[1] <= B[1]) || (A[3] == B[3] && Q[toupper(A[2])] < Q[toupper(B[2])]) || (A[3] < B[3] && Q[toupper(A[2])] < Q[toupper(B[2])])){
                                print "start_date " start_date " seems to be less than " end_date " end_date."
                           }
        else               {
                                print "Date is NOT in proper format."
                           }
                           }
        else               {
                                print "Date is NOT in proper format."
                           }
                           }                                  '
else
        echo "One of the argument is seems to be missing while running the script."
fi
 

Thanks,
R. Singh

1 Like

Given you are using a linux system, chances are GNU date is available and bash is recent enough for providing arithmetic operations. Try

echo $(($(date -d"$2" +%s) - $(date -d"$1" +%s)))
-22726800
1 Like

Thanks a lot RavinderSingh13, but fact is I need a check where it compares the following two arguments and returns a print statement : "start date is greater than end date. Incorrect form". It would be of great help if someone can code that.

Hello Chandan_Bose,

I am not sure you have tried to run my code or not, here are the examples of the script when I run it. Where script.ksh is the complete code as shown in POST#4 by me.

1st:
./script.ksh 19-MAY-2015 1-May-2015
Date is NOT in proper format.
2nd:
./script.ksh 19-MAY-2015 21-May-2015
start_date 19-MAY-2015 seems to be less than 21-May-2015 end_date.

Kindly do let me know if you have any queries on same.

Thanks,
R. Singh

Hi RavinderSingh, but my result wants start date to be less then end date

---------- Post updated at 03:06 PM ---------- Previous update was at 02:49 PM ----------

My apologies for not making the question clear.

Here it goes>>
I am having a problem. which I have described below>>

I have to run a script with the format : <File_name><Start_date><End_date>

example:

abcd.sh <01-MAY-2014> <01-JAN-2016>

but if I intentionally give an argument like >>
example:

abcd.sh <01-MAY-2014> <01-JAN-2012>

,
it should throw an error like " start date is more than end date "
I want a code which actually does so

Not clear. You have been given two examples of how to achieve the result you desire. Where now exactly are you stuck?

BTW, are those < and > part of the function parameters or not?

Hi RudiC,
I would definately look into it from the next time

Hello Chandan_Bose,

Still it is not clear but did some changes in script in case you need exact reason in output, then it may help you in same.

cat script.ksh
START_DATE=$1
END_DATE=$2;
if [[ -n $1 && -n $2 ]]
then
        awk -vstart_date="$START_DATE" -vend_date="$END_DATE" 'BEGIN{
                                                                        num=split("JAN FEB MAR APR MAY JUN JULY AUG SEPT OCT NOV DEC", array," ");
                                                                        for(i=1;i<=num;i++){
                                                                                                Q[array]=i
                                                                                           };
                                                                        split(start_date, A,"-");
                                                                        split(end_date, B,"-");
        if(A[3] < B[3]){VAL_YEAR="START date year is less than END date year."}
        if(A[3] > B[3]){VAL_YEAR="START date year is greater than END date year."}
        if(A[3] == B[3]){VAL_YEAR="START date year is same as END date year."}
        if(Q[toupper(A[2])] < Q[toupper(B[2])]){VAL_MONTH="START date month is before than END date month."}
        if(Q[toupper(A[2])] > Q[toupper(B[2])]){VAL_MONTH="START date month is after than END date month."}
        if(Q[toupper(A[2])] == Q[toupper(B[2])]){VAL_MONTH="START date month is same as END date month."}
        if(A[1] < B[1]){VAL_DATE="START date is before than END date."}
        if(A[1] > B[1]){VAL_DATE="START date is after than END date."}
        if(A[1] == B[1]){VAL_DATE="START date is same as END date."}
        if(A[3] <= B[3] && Q[toupper(A[2])] <= Q[toupper(B[2])]){
        if((A[3] == B[3] && Q[toupper(A[2])] == Q[toupper(B[2])] && A[1] < B[1]) || (A[3] == B[3] && Q[toupper(A[2])] < Q[toupper(B[2])]) || (A[3] < B[3] && Q[toupper(A[2])] == Q[toupper(B[2])] && A[1] < B[1]) || (A[3] < B[3] && Q[toupper(A[2])] < Q[toupper(B[2])])){
                                print "start_date " start_date " seems to be less than " end_date " end_date."
                           }
        else               {
                                print "Date is NOT in proper format because of following values:"
                                print VAL_YEAR ORS VAL_MONTH ORS VAL_DATE
                           }
                           }
        else               {
                                print "Date is NOT in proper format because of following values:"
                                print VAL_YEAR ORS VAL_MONTH ORS VAL_DATE
                           }
                           }                                  '
else
        echo "One of the argument is seems to be missing while running the script."
fi
 

So here is an example when we run script with a scenario as follows.

./script.ksh 29-MAY-2015 21-May-2015
Date is NOT in proper format because of following values:
START date year is same as END date year.
START date month is same as END date month.
START date is after than END date.

If above code doesn't meet your requirements then please port sample Input_file with expected output and with all the conditions you wanted in your requirement so that we could understand it more clearly.

Thanks,
R. Singh

1 Like

Hi RavinderSingh,

  Certainly your code served my purpose

---------- Post updated at 05:39 PM ---------- Previous update was at 03:33 PM ----------

#!/usr/bin/bash
clear
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8



if [ $# -lt 2 ]  ; then
        echo " Incorrect Number of Arguments";
        echo " Usage : Main_Script <FROM_DATE> <TO_DATE>";
        echo " Example : Main_Script 21-JUL-2015 30-JUL-2015";
        exit;
		
fi;

if [ $# == 2 ]; then
      if [[ $1 == [0-3][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9][0-9][0-9] ]]; then
	      if  [[ $2 == [0-3][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9][0-9][0-9] ]]; then 
		  START_DATE=$1
          END_DATE=$2;
          if [[ -n $1 && -n $2 ]]
          then
                 awk -vstart_date="$START_DATE" -vend_date="$END_DATE" 'BEGIN{
                                                                        num=split("JAN FEB MAR APR MAY JUN JULY AUG SEPT OCT NOV DEC", array," ");
                                                                        for(i=1;i<=num;i++){
                                                                                                Q[array]=i
                                                                                           };
                                                                        split(start_date, A,"-");
                                                                        split(end_date, B,"-");
        if(A[3] > B[3]){VAL_YEAR="START date year is greater than END date year."}
        if(Q[toupper(A[2])] > Q[toupper(B[2])]){VAL_MONTH="START date month is after than END date month."}
        if(A[1] > B[1]){VAL_DATE="START date is after than END date."}
        if(A[3] <= B[3] && Q[toupper(A[2])] <= Q[toupper(B[2])]){
        if((A[3] == B[3] && Q[toupper(A[2])] == Q[toupper(B[2])] && A[1] < B[1]) || (A[3] == B[3] && Q[toupper(A[2])] < Q[toupper(B[2])]) || (A[3] < B[3] && Q[toupper(A[2])] < Q[toupper(B[2])])){
                                echo "REPORT FROM " $1 "TO "$2;
                           }
        else               {
                                print "Date is NOT in proper format because of following values:"
                                print VAL_YEAR ORS VAL_MONTH ORS VAL_DATE
                           }
                           }
        else               {
                                print "Date is NOT in proper format because of following values:"
                                print VAL_YEAR ORS VAL_MONTH ORS VAL_DATE
                           }
                           }                                  '
else
        echo "One of the argument is seems to be missing while running the script."
                            fi;
						 echo "Incorrect date format";
		                 echo  $1;
                         echo "Usage : DD-MMM-YYYY";
		                 echo " Example :  Main_Script 21-JUL-2015 30-JUL-2015";
                        exit;
		              fi 
		   else
		   echo "Incorrect date format";
		   echo  $1;
          echo "Usage : DD-MMM-YYYY";
		  echo " Example :  Main_Script 21-JUL-2015 30-JUL-2015";
		  exit;
       fi; 
	   else
	    echo "Incorrect date format";
		echo  $2;
        echo "Usage : DD-MMM-YYYY";
		echo " Example :  Main_Script 21-JUL-2015 30-JUL-2015";
		exit;
	
		 
    fi;
	

Whenever I'm running the code , with the following inputs ./testingscript.sh 21-JUL-2015 21-JUN-2016

The message which it is throwing is >>
"Date is NOT in proper format because of following values:"

---------- Post updated at 05:51 PM ---------- Previous update was at 05:39 PM ----------

And then it is running into an infinite loop, instead of giving perfect input examples. Can I have a justification as to why is this happening

Hello Chandan_Bose,

Would like to request you if you are merging our code(provided by anyone in here forum members) into a large code(which we do not know your complete requirement and you haven't mentioned into post too), we could not give explanation for it like why it is not working, until/unless we go through your code completely(I had tested my script provided in pervious posts and is working fine for me). Though I have gone through your script and tried my best to correct it, please try it and let me know how it goes(Though I haven't tested it).

 #!/usr/bin/bash
clear
 export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
if [ $# -lt 2 ]  ; then
        echo " Incorrect Number of Arguments";
        echo " Usage : Main_Script <FROM_DATE> <TO_DATE>";
        echo " Example : Main_Script 21-JUL-2015 30-JUL-2015";
        exit;
 fi;
 if [ $# == 2 ];
then
      if [[ $1 == [0-3][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9][0-9][0-9]  && $2 == [0-3][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9][0-9][0-9] ]]
      then
                  START_DATE=$1
                  END_DATE=$2;
                                                                        awk -vstart_date="$START_DATE" -vend_date="$END_DATE" 'BEGIN{
                                                                        num=split("JAN FEB MAR APR MAY JUN JULY AUG SEPT OCT NOV DEC", array," ");
                                                                        for(i=1;i<=num;i++){
                                                                                                Q[array]=i
                                                                                           };
                                                                        split(start_date, A,"-");
                                                                        split(end_date, B,"-");
        if(A[3] > B[3]){VAL_YEAR="START date year is greater than END date year."}
        if(Q[toupper(A[2])] > Q[toupper(B[2])]){VAL_MONTH="START date month is after than END date month."}
        if(A[1] > B[1]){VAL_DATE="START date is after than END date."}
        if(A[3] <= B[3] && Q[toupper(A[2])] <= Q[toupper(B[2])]){
        if((A[3] == B[3] && Q[toupper(A[2])] == Q[toupper(B[2])] && A[1] < B[1]) || (A[3] == B[3] && Q[toupper(A[2])] < Q[toupper(B[2])]) || (A[3] < B[3] && Q[toupper(A[2])] < Q[toupper(B[2])])){
                                echo "REPORT FROM " $1 "TO "$2;
                           }
        else               {
                                print "Date is NOT in proper format because of following values:"
                                print VAL_YEAR ORS VAL_MONTH ORS VAL_DATE
                           }
                           }
        else               {
                                print "Date is NOT in proper format because of following values:"
                                print VAL_YEAR ORS VAL_MONTH ORS VAL_DATE
                           }
                           }                                  '
                  else
                                 echo "Incorrect date format";
                                 echo  $1;
                                 echo "Usage : DD-MMM-YYYY";
                                 echo " Example :  Main_Script 21-JUL-2015 30-JUL-2015";
                                 exit;
                  fi
        else
                                 echo "One of the argument is seems to be missing while running the script."
        fi

EDIT: Also adding a code with less if-else conditions by creating a function . This is only enhancement of my code in previous post.

START_DATE=$1
END_DATE=$2;
if [[ -n $1 && -n $2 ]]
then
        awk -vstart_date="$START_DATE" -vend_date="$END_DATE" '
                                          function check(Q,W,T, VAL)
                             {
                                if(Q < W)VAL="START date " T " is less than END date " T
                                if(Q > W)VAL="START date " T " is greater than END date " T
                                if(Q == W)VAL="START date " T " is equal to END date " T
                                return VAL
                             }
                                          function print1(A1,B1,C1)
                             {
                                print A1 ORS B1 ORS C1
                             }
                                                                BEGIN{
                                                                        num=split("JAN FEB MAR APR MAY JUN JULY AUG SEPT OCT NOV DEC", array," ");
                                                                        for(i=1;i<=num;i++){
                                                                                                Q[array]=i
                                                                                           };
                                                                        split(start_date, A,"-");
                                                                        split(end_date, B,"-");
        VAL_YEAR=check(A[3], B[3],"YEAR");
        VAL_MONTH=check(Q[toupper(A[2])], Q[toupper(B[2])],"MONTH");
        VAL_DATE=check(A[1], B[1],"DATE");
        if((A[3] == B[3] && Q[toupper(A[2])] == Q[toupper(B[2])] && A[1] < B[1]) || (A[3] == B[3] && Q[toupper(A[2])] < Q[toupper(B[2])]) || (A[3] < B[3] && Q[toupper(A[2])] == Q[toupper(B[2])] && A[1] < B[1]) || (A[3] < B[3] && Q[toupper(A[2])] < Q[toupper(B[2])])){
                                print "start_date " start_date " seems to be less than " end_date " end_date."
                           }
        else               {
                                print1(VAL_YEAR,VAL_MONTH,VAL_DATE);
                           }
                           }                                  '
else
        echo "One of the argument is seems to be missing while running the script."
fi
 

After running the script as above following are the different results.

 ./script.ksh 22-MAY-2015 21-May-2015
Date is NOT in proper format because of following values:
START date YEAR is equal to END date YEAR
START date MONTH is equal to END date MONTH
START date DATE is greater than END date DATE

 ./script.ksh 21-MAY-2015 21-May-2015
Date is NOT in proper format because of following values:
START date YEAR is equal to END date YEAR
START date MONTH is equal to END date MONTH
START date DATE is equal to END date DATE
  
 ./script.ksh 20-MAY-2015 21-May-2015
start_date 20-MAY-2015 seems to be less than 21-May-2015 end_date.
 

Thanks,
R. Singh

Pure bash approach:

IFS=- read D1 M1 Y1 D2 M2 Y2 <<< $1-$2
MTMP=$(locale abmon)
MTMP=${MTMP^^}
L1=${MTMP%%$M1*}
L2=${MTMP%%$M2*}
(( $(printf "%04d%02d%02d < %04d%02d%02d\n" $Y2 $((${#L2}/4+1)) $D2 $Y1 $((${#L1}/4+1)) $D1) ))  && echo "start later than end"