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

Hi all, I learned Perl and did not use for 5 yrs, so i returned to my teacher everything :-(. Would you please show me how to get report in this in perl?

- Here is my report.log
1,BEAR,2011-11-21 08:49:16.000,2011-11-21 08:53:13.910,San Francisco,, +, 2,BEAR,2011-11-21 08:49:16.000,2011-11-21 12:50:31.550,San Francisco,, +, 3,BEAR,2011-11-21 08:49:16.000,2011-11-21 08:49:19.987,San Francisco,, +, 4,HAWK,2011-11-21 10:36:26.000,2011-11-21 10:45:11.823,Los Angeles,,, 5,HAWK,2011-11-21 10:36:26.000,2011-11-21 12:41:17.763,Los Angeles,,, 6,HAWK,2011-11-21 10:41:12.000,2011-11-21 10:55:08.393,San Francisco,, +, 7,HAWK,2011-11-21 10:41:12.000,2011-11-21 15:46:24.707,San Francisco,, +, 8,HAWK,2011-11-21 10:41:12.000,2011-11-22 11:09:13.907,San Francisco,, +,
How do i search date from DATE1 to DATE2 and it tell me : Which team , location and how long? (longest time end time - start time) Example:
BEAR,San Francisco, timediff (2011-11-21 12:50:31.550 - 2011-11-21 08: +49:16.000) in hours HAWK,Los Anegles, timediff (2011-11-21 12:41:17.763 - 2011-11-21 10:36 +:26.000) in hours HAWK,San Francisco, timediff (2011-11-22 11:09:13.907 - 2011-11-21 10: +41:12.000) in hours
Thanks for sharing.

Replies are listed 'Best First'.
Re: Need help get longest timediff
by GrandFather (Saint) on Jan 04, 2012 at 01:16 UTC

    What have you tried? Without that we don't know where you got stuck so can't advise you where to look in the docs for help.

    PerlMonks is no more a code writing service now than it was 5 years ago, but it is still the place to get a leg up in learning to write Perl yourself. ;)

    Note that all your old nodes are still around so you can look back in wonder (or despair) at what you used to know.

    True laziness is hard work
Re: Need help get longest timediff
by ambrus (Abbot) on Jan 04, 2012 at 08:38 UTC

    Your question is a bit unclear, but for convenience I assume you want to subtract the two times in a line.

    You would think you could use the Date::Manip module, but that's only so if you don't need sub-second precision. Date::Manip handles dates that are a whole number of seconds only, and will silently discard the microsecond part of your dates when parsing them. If this is okay with you, something like this works.

    use Date::Manip::Date; my $d = Date::Manip::Date->new("2011-11-21 12:50:31.550"); my $e = $d->new("2011-11-21 08:49:16.000"); my $i = $e->calc($d); print $i->printf("%hys hours\n");

    Update 2012-01-07: apparently this doesn't answer all you're asking: you also want to find the minimal time difference for each pair of location and team. I'm lazy to write an answer now.

Re: Need help get longest timediff
by Anonymous Monk on Jan 04, 2012 at 01:14 UTC

    Text::CSV/Text::xSV

    #!/usr/bin/perl -- use strict; use warnings; use DateTime::Duration; use DateTime::Format::Human::Duration; use DateTime::Format::Natural; Main( @ARGV ); exit( 0 ); sub Main { @_ == 2 or return print Usage(); 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"; } sub Usage { <<"__USAGE__"; Usage: $0 startdate enddate $0 yesterday now $0 "last week" today $0 "2009-11-17" "2011-11-17" __USAGE__ } ## end sub Usage
Re: Need help get longest timediff
by Marshall (Canon) on Jan 04, 2012 at 09:51 UTC
    #!/usr/bin/perl -w use strict; use Data::Dump qw(pp); # the data is not strictly time sequential # I would as a first step, gather the data into records # based upon the team name and location # The easiest way with a HoA, Hash of Array. # although an extra dimension to the hash could be used # for the location. # %team_city_data is a HoA (Hash of Array) # my %team_city_data; while (<DATA>) { next if (/^\s*$/); #skip blank lines chomp; my ($team_name, $location) = (split /,/,$_)[1,4]; push @{$team_city_data{"$team_name-$location"}}, $_; } print "BEFORE the sort\n"; print pp(\%team_city_data),"\n"; # The time format of field[3] can be sorted by a # simple alpha sort because of the leading zero's. # This is an important thing when designing easily # parsable and sortable date/time formats # This will eventually give the earliest time and last # time for each team_location combination. # These times are extracted later as the first and last # of the sorted array's. foreach my $name_location (keys %team_city_data) { @{$team_city_data{$name_location}} = sort{ my ($Date_timeA) = (split(/,/, $a))[3]; my ($Date_timeB) = (split(/,/, $b))[3]; $Date_timeA cmp $Date_timeB }@{$team_city_data{$name_location}}; } print "AFTER the sort\n"; print pp(\%team_city_data),"\n"; # Instead of just printing the first and last dates # use some module to calculate the time difference # or use one of the built-in time functions. # The "tricky part" is how to get this far. # I leave the rest to you. foreach my $name_location (keys %team_city_data) { print "first: $team_city_data{$name_location}[0]\n"; print "last : $team_city_data{$name_location}[-1]\n"; print "\n"; } =prints....as final output (run yourself to see BEFORE and AFTER) first: 4,HAWK,2011-11-21 10:36:26.000,2011-11-21 10:45:11.823,Los Ange +les,,, last : 5,HAWK,2011-11-21 10:36:26.000,2011-11-21 12:41:17.763,Los Ange +les,,, first: 6,HAWK,2011-11-21 10:41:12.000,2011-11-21 10:55:08.393,San Fran +cisco,,, last : 8,HAWK,2011-11-21 10:41:12.000,2011-11-22 11:09:13.907,San Fran +cisco,,, first: 3,BEAR,2011-11-21 08:49:16.000,2011-11-21 08:49:19.987,San Fran +cisco,,, last : 2,BEAR,2011-11-21 08:49:16.000,2011-11-21 12:50:31.550,San Fran +cisco,,, =cut __DATA__ 1,BEAR,2011-11-21 08:49:16.000,2011-11-21 08:53:13.910,San Francisco,, +, 2,BEAR,2011-11-21 08:49:16.000,2011-11-21 12:50:31.550,San Francisco,, +, 3,BEAR,2011-11-21 08:49:16.000,2011-11-21 08:49:19.987,San Francisco,, +, 4,HAWK,2011-11-21 10:36:26.000,2011-11-21 10:45:11.823,Los Angeles,,, 5,HAWK,2011-11-21 10:36:26.000,2011-11-21 12:41:17.763,Los Angeles,,, 6,HAWK,2011-11-21 10:41:12.000,2011-11-21 10:55:08.393,San Francisco,, +, 7,HAWK,2011-11-21 10:41:12.000,2011-11-21 15:46:24.707,San Francisco,, +, 8,HAWK,2011-11-21 10:41:12.000,2011-11-22 11:09:13.907,San Francisco,, +,
Re: Need help get longest timediff
by Cristoforo (Curate) on Jan 05, 2012 at 02:52 UTC
    Like ambrus's solution, Time::Piece doesn't recognize fractions of a second, (I believe), and I had to edit them out before feeding to the the strptime method for Time::Piece.

    I noticed that the beginning times for each like Team-City pairing was the same. I didn't know if this was coincidence or that they would be the same in every case. This solution doesn't assume that.

    #!/usr/bin/perl use strict; use warnings; use Time::Piece; # core since Perl v5.9.5 my @data; open my $fh, "<", 'o33.txt' or die $!; while (<$fh>) { push @data, [ split /,/ ]; my ($start, $end) = map Time::Piece->strptime($_, "%Y-%m-%d %H:%M: +%S"), map s/\.\d\d\d$//r, @{ $data[-1] }[2,3]; push @{ $data[-1] }, $end - $start; # piggyback elapsed seconds $d +ata[r][c] } close $fh or die $!; my %seen; my @lines = grep {!$seen{ "@$_[1,4]" }++} sort {$a->[1] cmp $b->[1] || $b->[-1] <=> $a->[-1]} @data; for my $rec (@lines) { printf "%s,%s,%0.2f hours\n", @$rec[1,4], $rec->[-1]/3600; } __END__ *** input (o33.txt) 1,BEAR,2011-11-21 08:49:16.000,2011-11-21 08:53:13.910,San Francisco,, +, 2,BEAR,2011-11-21 08:49:16.000,2011-11-21 12:50:31.550,San Francisco,, +, 3,BEAR,2011-11-21 08:49:16.000,2011-11-21 08:49:19.987,San Francisco,, +, 4,HAWK,2011-11-21 10:36:26.000,2011-11-21 10:45:11.823,Los Angeles,,, 5,HAWK,2011-11-21 10:36:26.000,2011-11-21 12:41:17.763,Los Angeles,,, 6,HAWK,2011-11-21 10:41:12.000,2011-11-21 10:55:08.393,San Francisco,, +, 7,HAWK,2011-11-21 10:41:12.000,2011-11-21 15:46:24.707,San Francisco,, +, 8,HAWK,2011-11-21 10:41:12.000,2011-11-22 11:09:13.907,San Francisco,, +, *** output BEAR,San Francisco,4.02 hours HAWK,San Francisco,24.47 hours HAWK,Los Angeles,2.08 hours