Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

timestamp manipulation and evaluation

by jonathancnewcomb (Initiate)
on Aug 17, 2012 at 17:29 UTC ( #988043=perlquestion: print w/ replies, xml ) Need Help??
jonathancnewcomb has asked for the wisdom of the Perl Monks concerning the following question:

Perl Monks: I have an issue I have been attempting to resolve, I have a set of timestamps in 2 groups, lets say the following:

Group 1:

2012-08-17 12:00:00
2012-08-17 13:00:00

Group 2:

2012-08-17 09:00:00
2012-08-17 12:30:00

What I need is to be able to compare the differences between the 2 time stamps in each group, and then find the intersect time and duration between the 2 groups. Expected output should be something like:

2012-08-17 12:00:00 for 30 minutes
Any assistance would be greatly appreciated

Comment on timestamp manipulation and evaluation
Re: timestamp manipulation and evaluation
by kennethk (Abbot) on Aug 17, 2012 at 17:37 UTC

    What have you tried? What worked? What didn't? Code is always appreciated. See How do I post a question effectively?.

    When I need to do date-based math, I reach for DateTime. Which, in fact, will pretty much do what you need.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: timestamp manipulation and evaluation
by Kenosis (Priest) on Aug 17, 2012 at 18:22 UTC

    Consider splitting or regexing the Y,Mo,D,H,M,S out of the two time stamps, and then using Delta_DHMSM from Date::Calc to get the difference between those two stamps.

Re: timestamp manipulation and evaluation
by Anonymous Monk on Aug 17, 2012 at 19:44 UTC

    cpanp -i DateTime::Duration DateTime::Format::Human::Duration DateTime::Format::Natural

    #!/usr/bin/perl -- use strict; use warnings; use DateTime::Duration; use DateTime::Format::Human::Duration; use DateTime::Format::Natural; @ARGV = ( "last week", "today" ) unless @ARGV; my $dfn = DateTime::Format::Natural->new; my $start = $dfn->parse_datetime(shift); my $end = $dfn->parse_datetime(shift); my $diff = $end - $start; print "$end - $start = ", DateTime::Format::Human::Duration->new->format_duration($diff), "\n" +; __END__ 2012-08-04T00:00:00 - 2012-07-28T00:00:00 = 1 week
      Very nice example of these DateTime modules. I installed them and hope they are useful. But, it doesn't exactly figure the intersecting time of 2 sets of start, end times.

      But here is a way to do it that produces output like he wanted. There are other modules besides DateTime that would provide solutions, Time::Piece (Time::Piece was first released with perl v5.9.5), Date::Parse, Time::Local, and probably others.

      Either set of beg/end times could be switched, ($d1_beg and $d1_end could have been named $d2_beg, $d2_end and vice versa and this method would still be correct.


      #!/usr/bin/perl use strict; use warnings; use DateTime::Format::Strptime; use List::Util qw/ maxstr minstr /; # first released with perl v5.7.3 my $d1_beg = '2012-08-17 12:00:00'; my $d1_end = '2012-08-17 13:00:00'; my $d2_beg = '2012-08-17 09:00:00'; my $d2_end = '2012-08-17 12:30:00'; if ($d2_beg ge $d1_end or $d2_end le $d1_beg) { print "No common time\n"; } else { my $start = maxstr($d1_beg, $d2_beg); my $end = minstr($d1_end, $d2_end); my $dt = DateTime::Format::Strptime->new(pattern => "%F %T"); my @dt = map $dt->parse_datetime($_), $start, $end; my $dur = $dt[1]->delta_ms($dt[0])->in_units('minutes'); # duratio +n print "$start for $dur minutes\n"; } __END__ *** prints 2012-08-17 12:00:00 for 30 minutes

      Update: There is a nice discussion here about handling durations with DateTime.

Re: timestamp manipulation and evaluation
by Kenosis (Priest) on Aug 18, 2012 at 04:12 UTC

    Here's a subroutine that you can send those two time stamps to for the desired output (returns 0 if no intersecting time):

    use Modern::Perl; use Date::Calc qw/ Date_to_Time Time_to_Date /; say intersectingTime( '2012-08-17 12:00:00', '2012-08-17 13:00:00', '2012-08-17 09:00:00', '2012-08-17 12:30:00' ); sub intersectingTime { my ( $s1, $e1, $s2, $e2 ) = map Date_to_Time( /\d+/g ), @_; my $tStart = $s1 > $s2 ? $s1 : $s2; my $tEnd = $e1 < $e2 ? $e1 : $e2; $tEnd <= $tStart ? 0 : sprintf '%4d-%02d-%02d %02d:%02d:%02d for %02d minutes', Time_to_Date( $tStart ), ( $tEnd - $tStart ) / 60; }


    2012-08-17 12:00:00 for 30 minutes

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://988043]
Approved by lidden
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (10)
As of 2015-07-01 23:56 GMT
Find Nodes?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...

    Results (25 votes), past polls