Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Is it possible to use Time::HiRes to find the difference for the following format:
16:14:13.8167 16:23:14.6152
or am I better off writing my own parser?

Replies are listed 'Best First'.
Re: Time diff
by tall_man (Parson) on Mar 26, 2003 at 17:02 UTC
    Time::HiRes does not provide the constructors you will need (it uses gettimeofday for a precise current time). You'd be better off looking at DateTime::Precise, which can take input strings.

      I was curious how DateTime::Precise did things and noticed it uses Math::BigFloat. But 60*60*60*10000 fits in 32 unsigned bits, so you really need 33 since you are taking differences. But that will fit easily in the 52-odd bits of a C double so you can use regular Perl numbers for this and have perfect accuracy.

      The trick is to only use integer values (if you don't want to convince yourself that the round-off of fractional values won't bight you, which they probably wouldn't in this case anyway):

      #!/usr/bin/perl -w use strict; sub time2num { my $time= shift(@_); my( $hr, $min, $sec, $dec )= split /[:.]/, $time; $dec= substr( $dec."0000", 0, 4 ); return $dec + 10000*($sec+60*($min+60*$hr)); } sub num2time { my $tick= shift(@_); my $sign= '+'; if( $tick < 0 ) { $sign= '-'; $tick= -$tick; } my $sec= int( $tick/10000 ); $tick %= 10000; my $min= int( $sec/60 ); $sec %= 60; my $hr= int( $min/60 ); $min %= 60; return sprintf "%s%d:%02d:%02d.%04d", $sign, $hr, $min, $sec, $tick; } my $diff= time2num('16:14:13.8167') - time2num('16:23:14.6152'); printf "%.4f\n", $diff/10000; printf "%s\n", num2time($diff);
      prints
      -540.7985 -0:09:00.7985

                      - tye
      Thank, That did work, but now I have to find an average.
      Do you suggest the same module, I didn't see any doc supporting this?
        The module would work for finding an average time, like this:
        use strict; use DateTime::Precise; my $t1 = DateTime::Precise->new('2003. 3.26 16:14:13.8167'); my $t2 = DateTime::Precise->new('2003. 3.26 16:23:14.6152'); my $average = $t1 + ($t2 - $t1)/2.0;
        The subtraction produces a time in seconds, and the module provides a way to add seconds to a time. So just add half the difference and you will have the average.