in reply to Best way to do Time diff

I assumed that the number after dot is 0.0001s. If not change the constant value BASE.

However, as date is not part of the time stamp, the result is ONLY meaningful under certain context.
use strict; use constant BASE => 10000; print diff("00:17:12.0001", "23:18:09.0001");#this result would be mea +ningless and wrong, if it's 23 of today, and 00 of tomorrow. But this + is not an implementation thing, the request is a little bit ... sub diff { my ($t1, $t2) = @_; my ($h1, $m1, $s1, $ss1) = ($t1 =~ m/(\d+):(\d+):(\d+)\.(\d+)/); my ($h2, $m2, $s2, $ss2) = ($t2 =~ m/(\d+):(\d+):(\d+)\.(\d+)/); return (($h2 - $h1) * 3600 + ($m2 - $m1) * 60 + $s2 - $s1) * BASE ++ $ss2 - $ss1; }

Replies are listed 'Best First'.
Re: Re: Best way to do Time diff
by DaveH (Monk) on Feb 01, 2003 at 09:03 UTC

    Hi.

    In this situation, you could make the assumption that the times are from some sort of application log. In which case, the main circumstance you might need to handle would be the hour rolling over to 00:00:00.0000 (or greater). This implies, as before, that this is a rolling 24 hour period and the sub can't handle more than one day.

    If you state that the first parameter must be the earliest time, the second parameter the latest, you can handle this case quite easily. e.g.

    use strict; use constant BASE => 10000; print diff("23:59:59.9999", "00:00:00.0000"), "\n"; print diff("00:00:00.0000", "23:59:59.9999"), "\n"; sub diff { my ($before, $after) = @_; my ($h1, $m1, $s1, $ss1) = ($before =~ m/(\d+):(\d+):(\d+)\.(\d+)/ +); my ($h2, $m2, $s2, $ss2) = ($after =~ m/(\d+):(\d+):(\d+)\.(\d+)/ +); my $diff = (($h2-$h1)*3600 + ($m2-$m1)*60 + $s2-$s1)*BASE + $ss2-$ +ss1; return ($diff >= 0) ? $diff : $diff + (86400 * BASE); }

    For anything more complicated (e.g. handling daylight saving time transitions such as from GMT to BST, or vice versa), I would suggest looking into one of the Date::* or Time::* modules on CPAN.

    Updated: My sub didn't handle the case where the start and end times were the same, i.e. it returned 86400*BASE instead of 0. Fixed it with >= rather than >.

    Cheers,

    -- Dave :-)


    $q=[split+qr,,,q,~swmi,.$,],+s.$.Em~w^,,.,s,.,$&&$$q[pos],eg,print
      The problem is that it might rolling 24 hour period, 48 hour period, 72 hour period...

      We can only give the basic idea, but he needs to take care of more.

        This is always to problem whenever you deal with time/dates in code. Just where do you give up testing for every eventuality? Is is better to load a huge module like Date::Manip and be done with it, or is that overkill for such a simple pre-requisite like this?

        I can never decide...