in reply to Recursive method to check overlap of many date ranges

I have some code on CPAN that does this.. I think.

The example is take from the Data::Range::Compare::Stream::CookBook and is intended to compute exact downtime of a bank branch location when all 3 vnps are offline.

The concept is the same as computing network down time when there are multiple redundant links. You just want to know where the overlap is and how long each overlap is, then average the time out based on your current data.

Update: I found POSIX mktime was faster by a land slide than DateTime. Output is as follows:
Total Number of Trades: 2339
Total Trade Overlaps: 8034
Average Trade Overlap time in seconds: 45
Min Tade overlap time in seconds: 0
Max Tade overlap time in seconds: 918
Min number of overlapping trades: 2
Max number of overlapping trades: 5
Number of trades that did not overlap: 1222
Average trade time for ranges that did not overlap: 171

The input format for each file was as follows.

20120228162825 - 20120228164406
20120228170024 - 20120228171347
20120228172137 - 20120228173503
20120228173630 - 20120228174720
20120228180047 - 20120228180404
20120228181045 - 20120228181901
20120228183436 - 20120228183622
20120228185051 - 20120228185807
20120228190808 - 20120228192117
20120228193517 - 20120228194152
20120228194243 - 20120228195755
20120228195826 - 20120228200730
20120228201307 - 20120228201534
20120228202250 - 20120228203621
20120228204718 - 20120228205709
20120228210425 - 20120228211237
20120228211427 - 20120228212922
20120228213936 - 20120228214346
20120228215321 - 20120228215727
20120228220610 - 20120228221833
20120228223125 - 20120228224514
20120228225429 - 20120228230900
20120228232155 - 20120228232426
20120228233838 - 20120228234145
20120228234334 - 20120228235752
#!/usr/bin/perl use strict; use warnings; use POSIX qw(mktime); use lib qw(../lib); use Data::Range::Compare::Stream::Iterator::File; use Data::Range::Compare::Stream::Iterator::Compare::Asc; use Data::Range::Compare::Stream::Iterator::Consolidate::OverlapAsColu +mn; sub parse_line { my ($line)=@_; my $ref=[$line=~ /(\d+)/g]; foreach my $date (@$ref) { my @info=unpack('a4a2a2a2a2a2',$date); $info[0] -=1900; $info[1] -=1; $date=mktime($info[5],$info[4],$info[3],$info[2],$info[1],$info[0] +, 0, 0, 0); } return $ref; } my $cmp=new Data::Range::Compare::Stream::Iterator::Compare::Asc; my @it_list; foreach my $file (qw(posix_time_a.src posix_time_b.src posix_time_c.sr +c posix_time_d.src posix_time_e.src)) { my $iterator=new Data::Range::Compare::Stream::Iterator::File( parse_line=>\&parse_line, filename=>$file, NEW_FROM=>'Data::Range::Compare::Stream::PosixTime', ); # save our file iterator so we can figure out how many lines were in + each file push @it_list,$iterator; my $con=new Data::Range::Compare::Stream::Iterator::Consolidate::Ove +rlapAsColumn($iterator,$cmp); $cmp->add_consolidator($con); } my $total=0; my $time=0; my $non_overlaps=0; my $non_time=0; my $min_overlap=undef; my $max_overlap=0; my $max_overlap_count=0; my $min_overlap_count=undef; while($cmp->has_next) { my $result=$cmp->get_next; next if $result->is_empty; if($result->get_overlap_count>1) { my $overlap_time=$result->get_common->time_count; $max_overlap_count=$result->get_overlap_count if $max_overlap_coun +t < $result->get_overlap_count; if(defined($min_overlap_count)) { $min_overlap_count=$result->get_overlap_count if $min_overlap_co +unt > $result->get_overlap_count; } else { $min_overlap_count=$result->get_overlap_count; } $total +=$result->get_overlap_count; $time +=$overlap_time; $max_overlap=$overlap_time if $max_overlap < $overlap_time; if(defined($min_overlap)) { $min_overlap=$overlap_time if $min_overlap > $overlap_time; } else { $min_overlap=$overlap_time; } } else { $non_overlaps++; $non_time +=$result->get_common->time_count; } } my $total_trades=0; foreach my $it (@it_list) { $total_trades +=$it->get_pos; } print "Total Number of Trades: $total_trades\n"; print "Total Trade Overlaps: $total\n"; print "Average Trade Overlap time in seconds: ",int($time/$total),"\n" +; print "Min Tade overlap time in seconds: $min_overlap\n"; print "Max Tade overlap time in seconds: $max_overlap\n"; print "Min number of overlapping trades: $min_overlap_count\n"; print "Max number of overlapping trades: $max_overlap_count\n"; print "Number of trades that did not overlap: $non_overlaps\n"; print "Average trade time for ranges that did not overlap: ",int($non_ +time/$non_overlaps),"\n"; { package Data::Range::Compare::Stream::PosixTime; use strict; use warnings; use POSIX qw(strftime); use base qw(Data::Range::Compare::Stream); use constant NEW_FROM_CLASS=>'Data::Range::Compare::Stream::PosixTim +e'; sub format_range_value { my ($self,$value)=@_; strftime('%Y%m%d%H%M%S',localtime($value)); } sub range_start_to_string { my ($self)=@_; $self->format_range_value($self->range_start); } sub time_count { my ($self)=@_; $self->range_end - $self->range_start } sub range_end_to_string { my ($self)=@_; $self->format_range_value($self->range_end); } 1; }