Difference between two date values

bash-3.00$ date

Tue Oct 13 15:03:54 CEST 2015

start=`date +"%T" | awk -F":" '{print $2,$3}'`
echo $start
08 17
end=`date +"%T" | awk -F":" '{print $2,$3}'`
echo $end
08 37

how can I get the difference between above both timestamps, Im trying but getting errors: any one please help

bash-3.00$ echo `expr $end - $start`
expr: syntax error

bash-3.00$ echo  $(($end - $start))
bash: 08: value too great for base (error token is "08")

expected output for this case should be something like 00 20

man bash :

So, leadin the numbers with 10# . Try

end=( $(date +"%T") )
echo ${end[@]}
15 50 54
start='15 08 01'
echo $(( (10#${end[0]} - 10#${start[0]}) * 3600 + (10#${end[1]} - 10#${start[1]}) * 60 + 10#${end[2]} - 10#${start[2]} ))
2573

Hello sam@sam,

Could you please try following and let us know if this helps.

START=`date +"%T" | awk -F":" '{print $2 FS $3}'`
##### I ran following command after few mins
END=`date +"%T" | awk -F":" '{print $2 FS $3}'`
##### Then use following awk command to calculate difference.
awk -vstart=$START -vend=$END 'BEGIN{split(start, A,":");split(end, B,":");sec_start=A[1] * 60 + A[2];sec_end=B[1] * 60 + B[2];diff=sec_end - sec_start;print "Minutes \t Seconds" ORS int(diff/60) "\t\t " diff%60}'

You could use this in script too as per your convenience too.
NOTE: It is only looking for taking difference of minutes and seconds not dates.

Thanks,
R. Singh

No controls on 'sleep job' whatsoever :

#!/usr/bin/ksh
START="$(date +%s";"%T)"
sleep 2 # this is your job, my job is sleeping.
END="$(date +%s";"%T)"
printf "From=%s To=%s Dur=%s sec\n" "${START#*;}" "${END#*;}"  "$((${END%%;*}-${START%%;*}))"

Since we are using posix time duration will be correct for any job duration.
You can change the "%T" in START and END to reflect time more precise, and also do additional calculation to convert to minutes and hours on those variables.

You are not conclusive about your ultimate goal, but if you just want to measure the time a certain job needs to run you can just use the time command. The output will be similar to this:

# time <command>
real    0m3.01s
user    0m0.00s
sys     0m0.00s

What you are interested in most is perhaps the "real" part of the output. This is what the job took to run on the system. "user" and "sys" is the time spent in user mode and kernel mode respectively. This specific job (i used "sleep 3") took a tad over 3 seconds to run, needing (nearly) no time in user mode and no time in kernel mode.

I hope this helps.

bakunin

bash has the SECONDS variable:

START=$SECONDS 
... commands ... 
echo $(( SECONDS - START ))
31

Hi R.Singh your code match my requirement but at when use awk Im not getting expected results, can you please help me here

 START=`date +"%T" | awk -F":" '{print $2 FS $3}'`
 echo $START
31:36
 END=`date +"%T" | awk -F":" '{print $2 FS $3}'`
 echo $END
31:59
 awk -vstart=$START -vend=$END 'BEGIN{split(start, A,":");split(end, B,":");sec_start=A[1] * 60 + A[2];sec_end=B[1] * 60 + B[2];diff=sec_end - sec_start;print "Minutes \t Seconds" ORS int(diff/60) "\t\t " diff%60}'
Minutes          Seconds
0                0

When I enter awk comd its not existing from cmd prompt Where I need to exit forcefully
my OS details

uname -a
SunOS 5.10 Generic_148888-05 sun4u sparc SUNW,SPARC-Enterprise

Hello sam@sam,

On a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk .

Thanks,
R. Singh

Hello Ravinder singh, As suggested I have tried using /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk but only nawk seems to generate results but getting negative results: below are the 3 sample outputs

bash-3.00$ /usr/xpg4/bin/awk -vstart=$START -vend=$END 'BEGIN{split(start, A,":");split(end, B,":");sec_start=A[1] * 60 + A[2];sec_end=B[1] * 60 + B[2];diff=sec_end - sec_start;print "Minutes \t Seconds" ORS int(diff/60) "\t\t " diff%60}'
Invalid form for variable assignment: -vend=00:37


bash-3.00$ /usr/xpg6/bin/awk -vstart=$START -vend=$END 'BEGIN{split(start, A,":");split(end, B,":");sec_start=A[1] * 60 + A[2];sec_end=B[1] * 60 + B[2];diff=sec_end - sec_start;print "Minutes \t Seconds" ORS int(diff/60) "\t\t " diff%60}'
bash: /usr/xpg6/bin/awk: No such file or directory

 awk -vstart=$START -vend=$END 'BEGIN{split(start, A,":");split(end, B,":");sec_start=A[1] * 60 + A[2];sec_end=B[1] * 60 + B[2];diff=sec_end - sec_start;print "Minutes \t Seconds" ORS int(diff/60) "\t\t " diff%60}'
Minutes          Seconds
0                0

expected output should be some thing like:

Minutes          Seconds
0                    18

bash-3.00$ START=`date +"%T" | awk -F":" '{print $2 FS $3}'`
bash-3.00$ echo $START
00:19

bash-3.00$  END=`date +"%T" | awk -F":" '{print $2 FS $3}'`
bash-3.00$  echo $END
00:37

You got multiple solutions for date manipulation using various shells (bash,ksh) on this specific topic.
Also the forum search engine provides in-depth date manipulation from various members.

The awk solution provided by Ravinder provided will be the toughest to maintain if you don't know awk.

Resort to shell only, since you are using bash, RudiC provided a bashism, also i provided a solution in my post using ksh shell.

Hope that clears things out
Regards
Peasant.

In many versions of awk (including /usr/xpg4/bin/awk ), you have to separate the -v option from its option-argument. Try:

bash-3.00$ /usr/xpg4/bin/awk -v start=$START -v end=$END 'BEGIN{split(start, A,":");split(end, B,":");sec_start=A[1] * 60 + A[2];sec_end=B[1] * 60 + B[2];diff=sec_end - sec_start;print "Minutes \t Seconds" ORS int(diff/60) "\t\t " diff%60}'