Shell script to find difference between time stamps in milliseconds unix operating system

Hello, I am new to shell scripting.

This is the sample date and time stored in unix system.
here date part is common I will use shell script and cut this date part.

20221010042234.671 - 20221010042234.491
20221010132747.826 - 20221010132747.712
20221010060016.904 - 20221010060016.903

Input

132747.826 - 132747.712 
060016.904 - 060016.903
042234.671 - 042234.491

Expected output

0.18
0.11
0.001

Our unix system doesnt support mktime,use,my
date -d, most of the functions are missing finding it difficult to convert to epoch time.

I'm looking for assistance in writing a shell script to calculate the time difference.

awk -F, -v OFS=',' '{ print $1-$2 }' Simple

subtraction is not working for the 00th and 59th minutes.

@pupil6 , welcome , we hope you find the forum friendly and helpful

given - > 'Our unix system doesnt support mktime,use,my'
What is your OS (name and version details please) !

What shell are you using (or have access to) - again , give name and version !

thks

Hi Thank you.

HP-UX , B.11.31,ia64 - this is a course work

can you respond to that please. tks

see if the below fits your requirement

#!/bin/ksh

#
# using ksh date/time manipulation ...
#
echo $(printf "%(%.s)T" 13:27:47.826) - $(printf "%(%.s)T" 13:27:47.712) | bc -l

echo $(printf "%(%.s)T" 06:00:16.904) - $(printf "%(%.s)T" 06:00:16.903) | bc -l

echo $(printf "%(%.s)T" 04:22:34.671) - $(printf "%(%.s)T" 04:22:34.491) | bc -l

Hi , Thank you. Will check and give an update.

bc -l seems to be ideal here, because it works line by line from stdin.
Simply redirect its stdin to(from) the file.

as per @MadeInGermany ,
if you have the data in a file ....

cat data
20221010042234.671 - 20221010042234.491
20221010132747.826 - 20221010132747.712
20221010060016.904 - 20221010060016.903

# 
# bc -l will do the calculation directly on that
#
bc -lq <data
.180
.114
.001

fyi - that also works with the shortened timestamp

cat ms.data
042234.671 - 042234.491
060016.904 - 060016.903
132747.826 - 132747.712 

bc -lq <ms.data
.180
.001
.114

Thank you.
Yes data is in a file.

will check and let you know.

@munkeHoller

The issue arises in yyyymmddHHMMSS.uuu when the start/end times roll over a unit boundary (minute, hour, ...):

$ bc -lq <<'[][]'
> 20221010042200.315 - 20221010042159.925
> 20221010130001.315 - 20221010125958.677
> [][]
40.390
4042.638
$ 

Disregarding the common prefix in each pair of values, and reinforcing the limits of time expressions, the correct results would be:

22:00.315 - 21:59.925 should return 0.390
(0.075 remaining of the start second, and 0.315 in the end second).

13:00:01.315 - 12:59:58.677 should return 2.638;
(0.323 remaining in the start second, two whole seconds (59 and 00), and 0.315 of the final second).

The first error arises in the difference between treating 1 00 as decimal 100 versus 1:00 minute (adding 40).

The second example is much more fun. The hour step adds 6400 (10000 - 3600) seconds. The carry from 59->00 takes back 2400 (60 * (100 - 60)) seconds, so the final discrepancy is 4000.

I do not want to think about what happens when the timed period spans the last and first days of consecutive months. If you can justify the assumption that the timed period cannot exceed a whole day, you can use some modular arithmetic to fix the base-60 and base-24 carries in the HMS fields.

1 Like

ack, thanks.
looks like format (hence interpretation) is an issue, something along that below is probably what is needed, but more testing wrt boundaries being crossed to confirm, that'll be tomorrow for me.

#!/bin/ksh

echo $(printf "%(%.s)T" "2022-10-10 04:22:00.315") - $(printf "%(%.s)T" "2022-10-10 04:21:59.925") | bc -lq
.390000000
$ echo $(printf "%(%.s)T" "04:22:00.315") - $(printf "%(%.s)T" "04:21:59.925") | bc -lq
.390000000
$ echo $(printf "%(%.s)T" "2022-10-10 13:00:01.315") - $(printf "%(%.s)T" "2022-10-10 12:59:58.677") | bc -lq
2.638000000
$ echo $(printf "%(%.s)T" "13:00:01.315") - $(printf "%(%.s)T" "12:59:58.677") | bc -lq
2.638000000

PS: if you tested for what should've been returned, in the spirit of cooperation please share those.

hi,
Please accept my apologies , server got crashed. took sometime to bring back the server. I will test all the results and post the output.

Thank you.

1 Like

Please accept my apologies. server crashed and took sometime to bring it back. will test and let you know
Thank you.

hi,

Results.

adm@sample>bc -lq < d.txt
bc: illegal option -- q
adm@sample>bc -lq <d.txt
bc: illegal option -- q
adm@sample>bc -l <d.txt
0.180
0.114
.001

will verify with more input.

Thank you.

awk -F',' '{
split($10, D3, "." ); split ( $9, D2, ".");
match(D3[1], /(....)(..)(..)(..)(..)(..)/, T3)
match(D2[1], /(....)(..)(..)(..)(..)(..)/, T2)
if (match(D3[1], /(....)(..)(..)(..)(..)(..)/, T3)) {
ts3 = mktime(T3[1] " " T3[2] " " T3[3] " " T3[4] " " T3[5] " " T3[6])
}
if (match(D2[1], /(....)(..)(..)(..)(..)(..)/, T2)) {
ts2 = mktime(T2[1] " " T2[2] " " T2[3] " " T2[4] " " T2[5] " " T2[6])
}
ts= ts3 - ts2; if ( ts > 20 ) print $0 "," ts }' - 

The above solution is working in Linux server.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.