Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Timer subtraction

by Anonymous Monk
on Oct 06, 2017 at 08:17 UTC ( #1200802=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to subtract two different times. I tried to do a regular subtraction of variable. I think it won't work

my $first = "00:00:01:04"; my $last = "00:00:08:861"; my $output = $first-$last;

I am looking to extract each values(hour/min/sec/msec) seperatly after the subraction and assign it to variable and compare with the threshold. Is there any function in perl which does timer subtraction?

Replies are listed 'Best First'.
Re: Timer subtraction
by haukex (Monsignor) on Oct 06, 2017 at 08:57 UTC

    I normally use the DateTime family of modules for this kind of thing. It looks like what you have there are not absolute times, but timer durations, in which case you could try working with DateTime::Duration objects. (If you are instead working with absolute times, see here and here for solutions.)

    I looked into how to parse durations, and found DateTime::Format::Duration, but am having trouble getting it to parse milliseconds - I have a suspicion this may be a bug, and will look into this and update my node when I know more (Update: Bug reported.). Until then, parsing the duration manually seems to work, as follows. By the way, is it a typo that your milliseconds in $first only have two digits?

    use warnings; use strict; use DateTime::Duration; use DateTime::Format::Duration; my $first = "00:00:01:04"; my $last = "00:00:08:861"; sub my_parse_duration { my $in = shift; my %t; @t{qw/hours minutes seconds nanoseconds/} = $in=~/\A(\d\d):(\d\d):(\d\d):(\d\d\d?)\z/ or die "failed to parse '$in'"; $t{nanoseconds}*=1000000; # ms->ns return DateTime::Duration->new(%t); } $first = my_parse_duration($first); $last = my_parse_duration($last ); my $fmt_out = DateTime::Format::Duration->new( pattern=>'%H:%M:%S:%3N', normalize=>1 ); print $fmt_out->format_duration($first),"\n"; print $fmt_out->format_duration($last ),"\n"; $last->subtract_duration($first); print $fmt_out->format_duration($last ),"\n"; __END__ 00:00:01:004 00:00:08:861 00:00:07:857

      Thanks. Format duration is not working for me. In the last 3 print statements you are using format_duration which is not supported. Unfortunately, your code snippet fails. Yes, millisecs specified above was typo

        Format duration is not working for me. In the last 3 print statements you are using format_duration which is not supported. Unfortunately, your code snippet fails.

        The code snippet works fine for me. How does it fail for you? Please see How do I post a question effectively? and I know what I mean. Why don't you? - what are the exact error messages you get? Perhaps you have to install DateTime::Format::Duration?

        Even if not, you can still access the fields of the DateTime::Duration object yourself. This outputs the same thing as my above code:

        sub my_fmt_duration { my @t = shift->in_units('hours','minutes','seconds','nanoseconds') +; $t[3]/=1000000; # ns->ms return sprintf("%02d:%02d:%02d:%03d",@t); } print my_fmt_duration($first),"\n"; print my_fmt_duration($last ),"\n"; $last->subtract_duration($first); print my_fmt_duration($last ),"\n";
Re: Timer subtraction
by Discipulus (Monsignor) on Oct 06, 2017 at 08:38 UTC
    Hello, a fast search return Time::Piece to be agood candidate for such subtraction, but it seems does not handles milliseconds

    # pay attention to MSwin32 doublequotes perl -MTime::Piece -E "$t1=Time::Piece->strptime('23:58:59','%H:%M:%S' +);$t2=Time::Piece->strptime('23:56:58','%H:%M:%S');say $diff=($t1-$t2 +)" 121 # or directly subtracting perl -MTime::Piece -E "say Time::Piece->strptime('23:58:59','%H:%M:%S' +) - Time::Piece->strptime('23:56:58', '%H:%M:%S' )" 121

    L*

    PS Time::Hires and it's tv_interval supports millisecnds operations: see Re: time difference in milliseconds

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Timer subtraction (UPDATED)
by thanos1983 (Priest) on Oct 06, 2017 at 08:25 UTC

    Hello Anonymous Monk,

    I think you are looking for How do I find difference between two timestamps?.

    Update: Thanks to the idea of the fellow Monk haukex that you might want to measure the process time of your script between two points. In this case you can use Time::HiRes. If this is the case it can give you accuracy down to microseconds.

    Sample of code below:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use feature 'say'; use Time::HiRes qw(gettimeofday tv_interval); # measure elapsed time say 'Start counting'; my $t0 = [gettimeofday]; # do bunch of stuff here say 'I am doing my things here that I want to know the process time... +'; my $t1 = [gettimeofday]; say 'Finished counting'; print Dumper $t0; print Dumper $t1; my $t0_t1 = tv_interval $t0, $t1; say $t0_t1; my $elapsed = tv_interval ($t0, [gettimeofday]); say $elapsed; # $elapsed = tv_interval ($t0); # equivalent code __END__ $ perl test.pl Start counting I am doing my things here that I want to know the process time... Finished counting $VAR1 = [ 1507287063, 951261 ]; $VAR1 = [ 1507287063, 951274 ]; 1.3e-05 8.6e-05

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: Timer subtraction
by sundialsvc4 (Abbot) on Oct 06, 2017 at 12:21 UTC

    If we take the OP as literally written:

    my $first = "00:00:01:04"; my $last = "00:00:08:861"; my $output = $first-$last;
    ... the values of both $first and $last are quite-clearly strings.   In order to do arithmetic against them, they must be converted to a numeric form.   There are many, many libraries in the CPAN library that are concerned with time, and some of these are built in to the Core so as to be immediately available without installing.

    For instance, DateTime takes the now-common approach of treating a date/time as a Perl object.   You create one, either specifying a string to be decoded or the individual parts of a time, then you can simply manipulate it using the methods provided.

    In this particular case, where a string-format might not be automagically recognized on its own, you might need to break-apart the four parts of the string (e.g. with split() so that you can instantiate the object with the pieces-of-interest as shown in the documentation for DateTime:

    my $dt = DateTime->new( year => 1966, month => 10, day => 25, hour => 7, minute => 15, second => 47, nanosecond => 500000000, time_zone => 'America/Chicago', );

    You have a rich choice of time-handling modules at your disposal which will take care of all of the niggling problems associated with time encoding/decoding and time-arithmetic.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1200802]
Approved by Eily
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2017-11-18 09:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:













    Results (277 votes). Check out past polls.

    Notices?