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; }
In reply to Re: Recursive method to check overlap of many date ranges
by mshipper
in thread Recursive method to check overlap of many date ranges
by bigbot
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |