Re: Time modifications (173 Views)
Reply
Regular Advisor
UniRock
Posts: 122
Registered: ‎02-28-2008
Message 1 of 9 (173 Views)
Accepted Solution

Time modifications

Hi All,

Is there any inbuilt function in scripting to modify hh:mm:ss fields like adding/subtracting seconds or minutes etc?

My file contains few lines starting with:
hh:mm:ss

Thanks..
Acclaimed Contributor
James R. Ferguson
Posts: 21,184
Registered: ‎07-06-2000
Message 2 of 9 (173 Views)

Re: Time modifications

Hi:

Perl offers a wealth of ways and modules for adding and subtracting to dates and times.

Regards!

...JRF...
Honored Contributor
Laurent Menase
Posts: 1,079
Registered: ‎11-06-2003
Message 3 of 9 (173 Views)

Re: Time modifications

not really
I do
#!/usr/bin/ksh

function addseconds
{
typeset hms=$1
typeset -i delta=$2
res=$3
typeset -i H=${hms%%:*}
hms=${hms#*:}
typeset -i M=${hms%:*}
typeset -i S=${hms#*:}
typeset -i DM
typeset -i DH


S=S+delta
DM=S/60

S=S-DM*60
if (( S < 0 ))
then
S=S+60
DM=DM-1
fi
M=M+DM
DH=M/60
M=M-DH*60
if (( M <0 ))
then
M=M+60
DH=DH-1
fi

S=S+100
M=M+100
H=H+DH

eval "$3=${H}:${M#1}:${S#1}"

}

addseconds 10:10:10 90 xx
echo $xx
addseconds 10:10:10 -90 xx
echo $xx

Valued Contributor
Fredrik.eriksson
Posts: 237
Registered: ‎09-01-2008
Message 4 of 9 (173 Views)

Re: Time modifications

If you're just going to muck about with hh:mm:ss then something like this might do the trick:

use Time::Local;
sub altertime {
($hh,$mm,$ss) = split(/:/, shift);
($ss,$mm,$hh) = localtime((($hh-1)*60)*60+$mm*60+$ss+shift);
if($hh < 10){$hh = join('', "0", $hh);}
if($mm < 10){$mm = join('', "0", $mm);}
if($ss < 10){$ss = join('', "0", $ss);}
$time = join(":", $hh,$mm,$ss);
return $time;
}

$org_time = shift;
$time = altertime($org_time, shift);
printf("Original time: %s, Converted time: %s\n", $org_time, $time);

The last part is just for proof of concept. The script takes 2 input parameters, the original time (ex. 23:59:44) and how many seconds back or forward (ex. -3600 will return 22:59:44 and 3600 will make it 00:59:59).

# perl a.pl 23:59:59 -3600
Original time: 23:59:59, Converted time: 22:59:59
# perl a.pl 23:59:59 3600
Original time: 23:59:59, Converted time: 00:59:59

Best regards
Fredrik Eriksson
Honored Contributor
Hein van den Heuvel
Posts: 6,588
Registered: ‎05-19-2003
Message 5 of 9 (173 Views)

Re: Time modifications

For processing files I typically prefer perl or awk over shell scripting.

And when using Perl for serious scripts using the localtime function to normalize to time in seconds since 1970 is typically best.

For simple Perl scripts, converting to seconds since the begin of the day is often plenty good enough.

Something like

$last_time = $step = 0;
while (<>) {
if (/^(\d\d):(\d\d):(\d\d)/) {
$this_time = $1*3600 + $2*60 + $3;
$seconds = $this_time - $last_time;
$seconds += 86400 if $seconds < 0;
$last_time = $this_time;
$step++;
print "step $step took $seconds seconds.\n";
}
}


That +86400 is there in case the file wraps around midnight.

Cheers,
Hein

Honored Contributor
Laurent Menase
Posts: 1,079
Registered: ‎11-06-2003
Message 6 of 9 (173 Views)

Re: Time modifications

a little better than my previous one:
#!/usr/bin/ksh
function addseconds
{
typeset hms=$1
typeset -i delta=$2
res=$3
typeset R=""
typeset -i S=${hms%%:*}
hms=${hms#*:}
S=S*60+${hms%%:*}
hms=${hms#*:}
S=S*60+${hms%%:*}+delta
if (( S < 0 ))
then
R="-"
S=-S
fi
typeset -i M=S/60
S=S-M*60+100
typeset -i H=M/60
M=M-H*60+100
if [ -z "$res" ]
then
echo "${R}${H}:${M#1}:${S#1}"
else
eval "$res=${R}${H}:${M#1}:${S#1}"
fi
}

addseconds 10:10:10 3600
addseconds 10:10:10 3600 x
echo $x
addseconds 10:10:10 -3600 x
echo $x

Regular Advisor
UniRock
Posts: 122
Registered: ‎02-28-2008
Message 7 of 9 (173 Views)

Re: Time modifications

Hi All,

Thanks a lot for your replies..
But how would I use these scripts with my file say time1.

I have one file that has number of different entries containing hh:mm:ss. I need to advance these timings by say 30 seconds in every entry in this file (time1).

Honored Contributor
Hein van den Heuvel
Posts: 6,588
Registered: ‎05-19-2003
Message 8 of 9 (173 Views)

Re: Time modifications

Hmmm, ok, We were all kinda assuming you had an existing file to process and find differences.

To add times you you still should go to seconds, do the add as integers and convert back out.
Typically such conversion is just a divide by 24 to get HH, (or mod by 86400), a 'mod' function by 3600 to het MM and, a mod 60 to get the seconds.
You can of course also divide by 24 to get hours, subtract the whole hours and get minutes, divide by 60 to get minutes, subtract the whole minutes to get the seconds and toss into a formatted print.

Using perl you can coerce gmtime to to this:

$seconds = 123;
$hhmmss = (split /\s+/, scalar gmtime( $ seconds ))[3];
print $hhmmss"

00:02:03

Hint ... google for +hh:mm:ss +seconds
You;ll find plenty of perl/awk/shell alternatives.

Hein.
Valued Contributor
Fredrik.eriksson
Posts: 237
Registered: ‎09-01-2008
Message 9 of 9 (173 Views)

Re: Time modifications

Using my script and mixing in some bash scripting (just since it's easier) you should be able to do something like this:

assuming the file starts each line like this:
20:00:00 text or logs or whatever
20:00:01 text or logs or whatever2

# for i in $(cat time1); do date=$(echo $i | awk '{print $1}'); echo $i | replace "$date" "$(perl a.pl $date 30)" >> new_log.log; done

This is just a quick and dirty thing, I wouldn't use this in production environments but as a one time use it might work :)

It will produce a file name new_log.log which will contain the exact same entry's but with 30 seconds forward on all time stamps.

should output something like this:
20:00:30 text or logs or whatever
20:00:31 text or logs or whatever2

ps. it's untested :P ds.

Best regards
Fredrik Eriksson
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.