1748143 Members
3719 Online
108758 Solutions
New Discussion юеВ

Re: Time modifications

 
SOLVED
Go to solution
UniRock
Regular Advisor

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..
8 REPLIES 8
James R. Ferguson
Acclaimed Contributor

Re: Time modifications

Hi:

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

Regards!

...JRF...
Laurent Menase
Honored Contributor
Solution

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

Fredrik.eriksson
Valued Contributor

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
Hein van den Heuvel
Honored Contributor

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

Laurent Menase
Honored Contributor

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

UniRock
Regular Advisor

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).

Hein van den Heuvel
Honored Contributor

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.
Fredrik.eriksson
Valued Contributor

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