I've been running into the issue of having a SpanSet being incredibly slow when doing a ->contains on a DateTime->now object. I've tried spreading the spanset into an array of spans. That becomes much faster, but only if there is no time zone set on those spans. The moment I put time zones on those 'not unioned' spans I get a massive slowdown in computation time. This is going into a large scale project, and I was hoping that this feature would be able to be used since it does exactly what I need it to do!
Our goal is to take a group of spans and check if the time right now is within each span (basically a daily schedule across the globe). Here's a test program illustrating the problem I'm having. I'm just wondering if there is any way to make the ->contains faster. #!/usr/bin/perl use DateTime::Event::Recurrence; use DateTime::SpanSet; use DateTime::Infinite; use DateTime::Set; use DateTime; my ($total_span_set, $start, $end, $spanset); my @array; my %tzhash = ( '1' => 'America/Halifax', '2' => 'America/New_York', '3' => 'America/Chicago', '4' => 'America/Denver', '5' => 'America/Los_Angeles', '6' => 'America/Nome', '7' => 'Pacific/Honolulu', '8' => 'Asia/Tokyo', ); $x = 7; while ($x > 0 ){ # Make the set representing the work start times: M-F 9:00 and 13:00 $start = DateTime::Event::Recurrence->weekly ( days => $x%6+1, hours => 00 , minutes => 00); # Make the set representing the work end times: M-F 12:00 and 17:00 $end = DateTime::Event::Recurrence->weekly ( days => $x%6+1, hours => 23, minutes => 59); # Build a spanset from the set of starting points and ending points $spanset = DateTime::SpanSet->from_sets ( start_set => $start, end_set => $end ); if ($total_span_set){$total_span_set = $total_span_set->union($spanset)} else {$total_span_set = $spanset} push(@array, $spanset); $x--; } # Iterate from Thursday the 3rd to Monday the 6th my $it = $spanset->iterator (start => DateTime->new(year => 2003, month => 1, day => 3), before => DateTime->new(year => 2003, month => 1, day => 7)); while (my $span = $it->next) { my ($st, $end) = ($span->start(), $span->end()); print $st->day_abbr, " ", $st->hour, " to ", $end->hour, "\n"; } my $dt = DateTime->new(year => 2003, month => 2, day => 11, hour => 11); my $timer = DateTime->now; #Here I'm using the first way. Using a spanet seems very slow on 'contains' regardless of having a timezone set or not for the span my $x = 3; while( $x ){ $dt->set_time_zone($tzhash{$x%6 + 1}); #Setting a time zone to the SpanSet doesn't seem to affect search time $total_span_set->set_time_zone($tzhash{2}); if ($total_span_set->contains( $dt )){ print "Found time! \n"; } } $result = $timer - DateTime->now; print "Total time : ".$result->seconds."\n"; #An array of spans, this seems to be very fast without timezones set $timer = DateTime->now; $x = 3; while( $x ){ foreach(@array){ #Setting a time zone to the SpanSet/Spans really hoses search time $_->set_time_zone($tzhash{2}); if ($_->contains( $dt )){ print "Found time\n"; } } $x--; } $result = $timer - DateTime->now; print "Total time : ".$result->seconds."\n"; -- Per Jensen Bolder Thinking - Software Developer