help with expr command in script

Hi,

I am trying to code a unix function to calculate date difference between two date variables. I am stuck at a point where I am trying to convert hours into minutes. Below is the code I am doing.

 
function get_elapsed_time
{
export PROPS_FILE=temp.properties
export CURRENT_TIME=`date '+%T'`
export PREVIOUS_TIME=`grep ABC $PROPS_FILE |cut -c15-22`
echo $PREVIOUS_TIME
echo START_HR=`echo "$PREVIOUS_TIME" | awk '{print substr($0,1,2)}'`
echo $START_HR
echo END_HR=`echo "$CURRENT_TIME" | awk '{print substr($0,1,2)}'`
echo $END_HR
export START_MINS=`echo \`expr $START_HR \* 60\``
echo $START_MINS
}

Now the PREVIOUS_TIME will have value as say "26-Feb-10 08:16:23".
So the START_HR will have value as "08" and simlarly END_HR will have value as say "15".

The START_MINS should be like 08*60 which is 480. But when trying to run this temp.sh file i get the below error,

START_HR=08
END_HR=15
expr: syntax error

But if I run the same commands individually on the prompt, I get proper result. Its only while running the ksh script that the error is thrown.
#!/usr/bin/ksh

THe same command below runs perfectly fine on individual prompt
$export START_MINS=`echo \`expr $START_HR \* 60\``
$echo $START_MINS
480

Please can you advise.
Thanks

We don't need the echo.

export START_MINS=`expr $START_HR \* 60`

May I suggest using bc to do math calculation instead of expr? I am not suggesting that expr may be your problem. In fact i dont the solution to your problem, but I think to math stuff, I usuall use bc, for e.g

echo "1+2"|bc

You don't need expr (or bc or awk), but you do need to remove the leading zero or the number will be taken as octal, and 08 is not a valid octal number:

export START_MINS=$(( ${START_HR#0} * 60 ))

You indicated that you are using the Korn shell. If it is the latest version of the Korn shell rather than ksh88 or pdksh, the following script may help you

#!/usr/bin/ksh93
#
# diffdate "Tue, Feb 19, 2008 08:00:02 PM" "Wed, Feb 20, 2008 02:19:09 AM"
#

SDATE=$(printf '%(%s)T' "$1")
FDATE=$(printf '%(%s)T' "$2")

[[ $# -ne 2 ]] && {
   print "Usage: diffdate start-date finish-date"
   exit 1
}

DIFF=$(($FDATE-$SDATE))

SECS=$(($DIFF % 60))
MINS=$(($DIFF % (60 * 60) / 60))
HOURS=$(($DIFF / (60 * 60)))

printf "%02d:%02d:%02d\n" $HOURS $MINS $SECS

exit 0

No need to use command substitute and/or expr or bc. Use builtin, it's enough.
Ksh, bash, zsh, ... but not ex. in dash. (posix not include this, so using ex. dash you need command substitution - thanks for cfajohnson).

(( SECS= DIFF % 60                  ))
(( MINS= DIFF % (60 * 60) / 60  ))
(( HOURS= DIFF / (60 * 60)        ))

Posix version need command substitution ex. in dash, works also in ksh, bash, ...

SECS=$((  DIFF % 60                  ))
MINS=$((  DIFF % (60 * 60) / 60  ))
HOURS=$(( DIFF / (60 * 60)        ))

And if you not use ksh (prev. printf using), then use ex. gnu date. Take epoc time and calculate.

...
SDATE=$( date -d "$1" '+%s' )
FDATE=$( date -d "$2" '+%s' )
(( DIFF = FDATE - SDATE ))
...

This code will not work in dash; it is not POSIX syntax.

The POSIX syntax, which will work in all the shells you mentioned, is:

SECS=$((  $DIFF % 60   ))
MINS=$((  $DIFF % (60 * 60) / 60  ))
HOURS=$(( $DIFF / (60 * 60) ))

Hi All,
Thanks for so many suggestions.
Removing echo, does not work as it still gives syntax error.

Removing the leading zero also does not work. This gives an error as *60 not found. Since * is used as wild card.

I am using ksh, so I guess date -d won't work in ksh.
If i use the printf command, the date is not calculated. The error is thrown as
The output is like below.
1-Mar-10 03:56:51
START_TIME=()T
END_TIME=()T
()T-()T: syntax error

I tried using it this way.

function get_elapsed_time
{
export PROPS_FILE=/apps/taskman/scripts/dailyreports/temp_file.properties
export CURRENT_TIME=`date '+%e-%h-%y %T'`
export PREVIOUS_TIME=`grep ABC $REPORT_PROPS_FILE |cut -d= -f2`
echo $PREVIOUS_TIME
START_TIME=$(printf '%(%s)T' "$PREVIOUS_TIME")
echo $START_TIME
END_TIME=$(printf '%(%s)T' "$CURRENT_TIME")
echo $END_TIME
DIFF=$(($END_TIME-$START_TIME))
echo $DIFF
SECS=$(($DIFF % 60))
echo $SECS
MINS=$(($DIFF % (60 * 60) / 60 ))
echo $MINS
}

Its still not working. :frowning: Is there some other way to use printf command in unix?

---------- Post updated 1st Mar 2010 at 12:09 AM ---------- Previous update was 28th Feb 2010 at 11:42 PM ----------

I think the version is ksh88. I tried to print the SECONDS variable and its an integer value. So it should be a ksh88 rt?

---------- Post updated at 12:16 AM ---------- Previous update was at 12:09 AM ----------

Hi All,

Its working now!! :slight_smile:

I am using the same original code and just modified the export command. Yes, removing echo does help.

function get_elapsed_time
{
export PROPS_FILE=temp.properties
export CURRENT_TIME=`date '+%T'`
export PREVIOUS_TIME=`grep ABC $PROPS_FILE |cut -c15-22`
echo $PREVIOUS_TIME
START_HR=`echo "$PREVIOUS_TIME" | awk '{print substr($0,1,2)}'`
echo $START_HR
END_HR=`echo "$CURRENT_TIME" | awk '{print substr($0,1,2)}'`
echo $END_HR
START_MINS=`expr $START_HR \* 60`
echo $START_MINS
}

Thanks a lot!!

substr is a test ksh88/ksh93.

a="0123456"
echo ${a:2:3}   # output is 234

date is not builtin command, it's in command in your system. -d option is in gnu date, not ex. in bsd date.

printf is builtin command in ksh93. So man ksh93 include documentation to use printf.

You don't need export in your code. Local variables is enough. Environment variables (export variable) are needed if you call subprocess and subprocess need those variables value also.

If you like to use ksh93, check download. Maybe your system is still supported.