I've attached a patch for current() and set_time_zone().

There are no tests.

2008/12/19 Elliot Shank <p...@galumph.com>:
> I now have a case where I'm trying to set up a set of weekly recurrences
> that cover the entire week: if I've got Tuesday at 5pm and Thursday at
> 11:30am, there are two SpanSets, on the covers the Tuesday to Thursday range
> and one that covers the Thursday to Tuesday range.  I'm running into
> problems with the degenerate case where there's only one point for the week.
> If I don't set the time zone on the SpanSet, I get what I'm expecting, with
> one exception that I can work around.  However, if I touch the time zone,
> then things go awry, even if I use the intermediary floating time zone
> trick.
>
> If I don't set the time zone, I get correct results, except for precisely at
> the time of the single anchor, but in that case, only the end is wrong, and
> I can easily work around that.
>
> If I do set the time zone, pulling the currently effective span from the set
> results in spans that are infinite in both directions.
>
>
>          With no time zone changes,   now start: 2008-12-15T08:30:00 end:
> 2008-12-22T08:30:00
>          With no time zone changes,  6:30 start: 2008-12-08T08:30:00 end:
> 2008-12-15T08:30:00
>          With no time zone changes,  7:30 start: 2008-12-08T08:30:00 end:
> 2008-12-15T08:30:00
>          With no time zone changes,  8:30 start: 2008-12-15T08:30:00 end:
> inf
>          With no time zone changes,  9:30 start: 2008-12-15T08:30:00 end:
> 2008-12-22T08:30:00
>          With no time zone changes, 10:30 start: 2008-12-15T08:30:00 end:
> 2008-12-22T08:30:00
>          With no time zone changes, 11:30 start: 2008-12-15T08:30:00 end:
> 2008-12-22T08:30:00
>           With time zone specified,   now start: -inf end: inf
>           With time zone specified,  6:30 start: -inf end: inf
>           With time zone specified,  7:30 start: -inf end: inf
>           With time zone specified,  8:30 start: -inf end: inf
>           With time zone specified,  9:30 start: -inf end: inf
>           With time zone specified, 10:30 start: -inf end: inf
>           With time zone specified, 11:30 start: -inf end: inf
> With intermediary floating time zone,   now start: -inf end: inf
> With intermediary floating time zone,  6:30 start: -inf end: inf
> With intermediary floating time zone,  7:30 start: -inf end: inf
> With intermediary floating time zone,  8:30 start: -inf end: inf
> With intermediary floating time zone,  9:30 start: -inf end: inf
> With intermediary floating time zone, 10:30 start: -inf end: inf
> With intermediary floating time zone, 11:30 start: -inf end: inf
>
>
> -----
>
> use DateTime;
> use DateTime::Event::Recurrence;
> use DateTime::SpanSet;
>
>
> my $recurrence =
>   DateTime::Event::Recurrence->weekly(
>       days => 1, hours => 8, minutes => 30,
>   );
>
> my $base_span_set =
>   DateTime::SpanSet
>       ->from_sets(start_set => $recurrence, end_set => $recurrence);
>
> dump_end_points(
>   $base_span_set,
>   'With no time zone changes',
> );
> dump_end_points(
>   $base_span_set
>       ->clone()
>       ->set_time_zone('America/Chicago'),
>   'With time zone specified',
> );
> dump_end_points(
>   $base_span_set
>       ->clone()
>       ->set_time_zone('floating')
>       ->set_time_zone('America/Chicago'),
>   'With intermediary floating time zone',
> );
>
> sub dump_end_points {
>   my ($span_set, $name) = @_;
>
>   my $format = "%36s, %5s start: %s end: %s\n";
>
>   my $span = $span_set->current( DateTime->now() )->span();
>   printf $format, $name, 'now', $span->start(), $span->end();
>
>   foreach my $hour (6..11) {
>       $span =
>           $span_set
>               ->current(
>                   DateTime->new(
>                       year    => 2008,
>                       month   => 12,
>                       day     => 15,
>                       hour    => $hour,
>                       minute  => 30,
>                   )
>               )
>               ->span();
>       printf $format, $name, "$hour:30", $span->start(), $span->end();
>   }
> }
>
--- /Users/flavioglock/projects/datetime/perl-date-time/modules/DateTime-Set/trunk/lib/DateTime/SpanSet.pm	2008-06-21 09:37:43.000000000 +0200
+++ lib/DateTime/SpanSet.pm	2008-12-19 23:06:33.000000000 +0100
@@ -85,12 +85,12 @@
             if ( ref($min) )
             {
                 $min = $min->clone;
-                $min->set_time_zone( $tz );
+                $min->set_time_zone( 'floating' );
             }
             if ( ref($max) )
             {
                 $max = $max->clone;
-                $max->set_time_zone( $tz );
+                $max->set_time_zone( 'floating' ); 
             }
             return Set::Infinite::_recurrence->new( $min, $max );
         },
@@ -292,10 +292,30 @@
 sub current {
     my $self = shift;
 
-    my $return = $self->intersected_spans( $_[0] );
+    my $previous;
+    my $next;
+    {
+        my $min;
+        $min = $_[0]->min if UNIVERSAL::can( $_[0], 'union' );
+        $min = $_[0] if ! defined $min;
+        return undef if ! ref( $min ) && $min == INFINITY;
+        my $span = DateTime::Span->from_datetimes( end => $min );
+        my $iterator = $self->intersection( $span );
+        $previous = $iterator->previous;
+        $span = DateTime::Span->from_datetimes( start => $min );
+        $iterator = $self->intersection( $span );
+        $next = $iterator->next;
+    }
+    return $previous unless defined $next;
+
+    my $dt1 = defined $previous
+        ? $next->union( $previous )
+        : $next;
+
+    my $return = $dt1->intersected_spans( $_[0] );
 
-    $return = $self->previous( $_[0] )
-        if ( ! defined $return->max );
+    $return = $previous
+        if !defined $return->max;
 
     bless $return, 'DateTime::SpanSet'
         if defined $return;

Reply via email to