6 use Params::Validate qw( validate SCALAR BOOLEAN OBJECT CODEREF ARRAYREF );
 
   7 use DateTime 0.12;  # this is for version checking only
 
   8 use DateTime::Duration;
 
  10 use Set::Infinite 0.59;
 
  11 use Set::Infinite::_recurrence;
 
  13 use vars qw( $VERSION );
 
  15 use constant INFINITY     =>       100 ** 100 ** 100 ;
 
  16 use constant NEG_INFINITY => -1 * (100 ** 100 ** 100);
 
  25     # (not a class method)
 
  27     # checks that the parameter is an object, and
 
  28     # also protects the object against mutation
 
  31         unless defined $_[0];      # error
 
  33         if ref( $_[0] );           # "immutable" datetime
 
  34     return DateTime::Infinite::Future->new 
 
  35         if $_[0] == INFINITY;      # Inf
 
  36     return DateTime::Infinite::Past->new
 
  37         if $_[0] == NEG_INFINITY;  # -Inf
 
  41 sub _fix_return_datetime {
 
  42     my ( $dt, $dt_arg ) = @_;
 
  45     # (not a class method)
 
  47     # checks that the returned datetime has the same
 
  48     # time zone as the parameter
 
  53     return unless $dt_arg;
 
  54     if ( $dt_arg->can('time_zone_long_name') &&
 
  55          !( $dt_arg->time_zone_long_name eq 'floating' ) )
 
  57         $dt->set_time_zone( $dt_arg->time_zone );
 
  63     # deprecated method - use map() or grep() instead
 
  64     my ( $self, $callback ) = @_;
 
  65     my $class = ref( $self );
 
  66     my $return = $class->empty_set;
 
  67     $return->{set} = $self->{set}->iterate( 
 
  70             $callback->( $min->clone ) if ref($min);
 
  77     my ( $self, $callback ) = @_;
 
  78     my $class = ref( $self );
 
  79     die "The callback parameter to map() must be a subroutine reference"
 
  80         unless ref( $callback ) eq 'CODE';
 
  81     my $return = $class->empty_set;
 
  82     $return->{set} = $self->{set}->iterate( 
 
  84             local $_ = $_[0]->min;
 
  85             next unless ref( $_ );
 
  87             my @list = $callback->();
 
  88             my $set = Set::Infinite::_recurrence->new();
 
  89             $set = $set->union( $_ ) for @list;
 
  97     my ( $self, $callback ) = @_;
 
  98     my $class = ref( $self );
 
  99     die "The callback parameter to grep() must be a subroutine reference"
 
 100         unless ref( $callback ) eq 'CODE';
 
 101     my $return = $class->empty_set;
 
 102     $return->{set} = $self->{set}->iterate( 
 
 104             local $_ = $_[0]->min;
 
 105             next unless ref( $_ );
 
 107             my $result = $callback->();
 
 108             return $_ if $result;
 
 115 sub add { return shift->add_duration( DateTime::Duration->new(@_) ) }
 
 117 sub subtract { return shift->subtract_duration( DateTime::Duration->new(@_) ) }
 
 119 sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) }
 
 122     my ( $self, $dur ) = @_;
 
 123     $dur = $dur->clone;  # $dur must be "immutable"
 
 125     $self->{set} = $self->{set}->iterate(
 
 127             my $min = $_[0]->min;
 
 128             $min->clone->add_duration( $dur ) if ref($min);
 
 130         backtrack_callback => sub { 
 
 131             my ( $min, $max ) = ( $_[0]->min, $_[0]->max );
 
 135                 $min->subtract_duration( $dur );
 
 140                 $max->subtract_duration( $dur );
 
 142             return Set::Infinite::_recurrence->new( $min, $max );
 
 149     my ( $self, $tz ) = @_;
 
 151     $self->{set} = $self->{set}->iterate(
 
 153             my $min = $_[0]->min;
 
 154             $min->clone->set_time_zone( $tz ) if ref($min);
 
 156         backtrack_callback => sub {
 
 157             my ( $min, $max ) = ( $_[0]->min, $_[0]->max );
 
 161                 $min->set_time_zone( $tz );
 
 166                 $max->set_time_zone( $tz );
 
 168             return Set::Infinite::_recurrence->new( $min, $max );
 
 176     my %args = validate( @_,
 
 177                          { locale => { type => SCALAR | OBJECT,
 
 181     $self->{set} = $self->{set}->iterate( 
 
 183             my $min = $_[0]->min;
 
 184             $min->clone->set( %args ) if ref($min);
 
 190 sub from_recurrence {
 
 196     # Parameter renaming, such that we can use either
 
 197     #   recurrence => xxx   or   next => xxx, previous => xxx
 
 198     $param{next} = delete $args{recurrence} || delete $args{next};
 
 199     $param{previous} = delete $args{previous};
 
 201     $param{span} = delete $args{span};
 
 202     # they might be specifying a span using begin / end
 
 203     $param{span} = DateTime::Span->new( %args ) if keys %args;
 
 207     die "Not enough arguments in from_recurrence()"
 
 208         unless $param{next} || $param{previous}; 
 
 210     if ( ! $param{previous} ) 
 
 215                     _callback_previous ( _fix_datetime( $_[0] ), $param{next}, $data );
 
 220         my $previous = $param{previous};
 
 223                     $previous->( _fix_datetime( $_[0] ) );
 
 227     if ( ! $param{next} ) 
 
 232                     _callback_next ( _fix_datetime( $_[0] ), $param{previous}, $data );
 
 237         my $next = $param{next};
 
 240                     $next->( _fix_datetime( $_[0] ) );
 
 245     $max = $param{previous}->( DateTime::Infinite::Future->new );
 
 246     $min = $param{next}->( DateTime::Infinite::Past->new );
 
 247     $max = INFINITY if $max->is_infinite;
 
 248     $min = NEG_INFINITY if $min->is_infinite;
 
 250     my $base_set = Set::Infinite::_recurrence->new( $min, $max );
 
 251     $base_set = $base_set->intersection( $param{span}->{set} )
 
 254     # warn "base set is $base_set\n";
 
 258             $base_set->_recurrence(
 
 270     my %args = validate( @_,
 
 277     $self->{set} = Set::Infinite::_recurrence->new;
 
 278     # possible optimization: sort datetimes and use "push"
 
 279     for( @{ $args{dates} } ) 
 
 281         # DateTime::Infinite objects are not welcome here,
 
 282         # but this is not enforced (it does't hurt)
 
 284         carp "The 'dates' argument to from_datetimes() must only contain ".
 
 286             unless UNIVERSAL::can( $_, 'utc_rd_values' );
 
 288         $self->{set} = $self->{set}->union( $_->clone );
 
 298     return bless { set => Set::Infinite::_recurrence->new }, $class;
 
 302     my $self = bless { %{ $_[0] } }, ref $_[0];
 
 303     $self->{set} = $_[0]->{set}->copy;
 
 307 # default callback that returns the 
 
 308 # "previous" value in a callback recurrence.
 
 310 # This is used to simulate a 'previous' callback,
 
 311 # when then 'previous' argument in 'from_recurrence' is missing.
 
 313 sub _callback_previous {
 
 314     my ($value, $callback_next, $callback_info) = @_; 
 
 315     my $previous = $value->clone;
 
 317     return $value if $value->is_infinite;
 
 319     my $freq = $callback_info->{freq};
 
 320     unless (defined $freq) 
 
 322         # This is called just once, to setup the recurrence frequency
 
 323         my $previous = $callback_next->( $value );
 
 324         my $next =     $callback_next->( $previous );
 
 325         $freq = 2 * ( $previous - $next );
 
 326         # save it for future use with this same recurrence
 
 327         $callback_info->{freq} = $freq;
 
 330     $previous->add_duration( $freq );  
 
 331     $previous = $callback_next->( $previous );
 
 332     if ($previous >= $value) 
 
 334         # This error happens if the event frequency oscilates widely
 
 335         # (more than 100% of difference from one interval to next)
 
 336         my @freq = $freq->deltas;
 
 337         print STDERR "_callback_previous: Delta components are: @freq\n";
 
 338         warn "_callback_previous: iterator can't find a previous value, got ".
 
 339             $previous->ymd." after ".$value->ymd;
 
 344         $previous1 = $previous->clone;
 
 345         $previous = $callback_next->( $previous );
 
 346         return $previous1 if $previous >= $value;
 
 350 # default callback that returns the 
 
 351 # "next" value in a callback recurrence.
 
 353 # This is used to simulate a 'next' callback,
 
 354 # when then 'next' argument in 'from_recurrence' is missing.
 
 357     my ($value, $callback_previous, $callback_info) = @_; 
 
 358     my $next = $value->clone;
 
 360     return $value if $value->is_infinite;
 
 362     my $freq = $callback_info->{freq};
 
 363     unless (defined $freq) 
 
 365         # This is called just once, to setup the recurrence frequency
 
 366         my $next =     $callback_previous->( $value );
 
 367         my $previous = $callback_previous->( $next );
 
 368         $freq = 2 * ( $next - $previous );
 
 369         # save it for future use with this same recurrence
 
 370         $callback_info->{freq} = $freq;
 
 373     $next->add_duration( $freq );  
 
 374     $next = $callback_previous->( $next );
 
 377         # This error happens if the event frequency oscilates widely
 
 378         # (more than 100% of difference from one interval to next)
 
 379         my @freq = $freq->deltas;
 
 380         print STDERR "_callback_next: Delta components are: @freq\n";
 
 381         warn "_callback_next: iterator can't find a previous value, got ".
 
 382             $next->ymd." before ".$value->ymd;
 
 387         $next1 = $next->clone;
 
 388         $next =  $callback_previous->( $next );
 
 389         return $next1 if $next >= $value;
 
 398     $span = delete $args{span};
 
 399     $span = DateTime::Span->new( %args ) if %args;
 
 401     return $self->intersection( $span ) if $span;
 
 406 # next() gets the next element from an iterator()
 
 407 # next( $dt ) returns the next element after a datetime.
 
 410     return undef unless ref( $self->{set} );
 
 414         if ( $self->{set}->_is_recurrence )
 
 416             return _fix_return_datetime(
 
 417                        $self->{set}->{param}[0]->( $_[0] ), $_[0] );
 
 421             my $span = DateTime::Span->from_datetimes( after => $_[0] );
 
 422             return _fix_return_datetime(
 
 423                         $self->intersection( $span )->next, $_[0] );
 
 427     my ($head, $tail) = $self->{set}->first;
 
 428     $self->{set} = $tail;
 
 429     return $head->min if defined $head;
 
 433 # previous() gets the last element from an iterator()
 
 434 # previous( $dt ) returns the previous element before a datetime.
 
 437     return undef unless ref( $self->{set} );
 
 441         if ( $self->{set}->_is_recurrence ) 
 
 443             return _fix_return_datetime(
 
 444                       $self->{set}->{param}[1]->( $_[0] ), $_[0] );
 
 448             my $span = DateTime::Span->from_datetimes( before => $_[0] );
 
 449             return _fix_return_datetime(
 
 450                       $self->intersection( $span )->previous, $_[0] );
 
 454     my ($head, $tail) = $self->{set}->last;
 
 455     $self->{set} = $tail;
 
 456     return $head->max if defined $head;
 
 460 # "current" means less-or-equal to a datetime
 
 464     return undef unless ref( $self->{set} );
 
 466     if ( $self->{set}->_is_recurrence )
 
 468         my $tmp = $self->next( $_[0] );
 
 469         return $self->previous( $tmp );
 
 472     return $_[0] if $self->contains( $_[0] );
 
 473     $self->previous( $_[0] );
 
 478     # return $_[0] if $self->contains( $_[0] );
 
 479     my $dt1 = $self->current( $_[0] );
 
 480     my $dt2 = $self->next( $_[0] );
 
 482     return $dt2 unless defined $dt1;
 
 483     return $dt1 unless defined $dt2;
 
 485     my $delta = $_[0] - $dt1;
 
 486     return $dt1 if ( $dt2 - $delta ) >= $_[0];
 
 493     return undef unless ref( $self->{set} );
 
 497     $span = delete $args{span};
 
 498     $span = DateTime::Span->new( %args ) if %args;
 
 500     my $set = $self->clone;
 
 501     $set = $set->intersection( $span ) if $span;
 
 503     return if $set->{set}->is_null;  # nothing = empty
 
 505     # Note: removing this line means we may end up in an infinite loop!
 
 506     ## return undef if $set->{set}->is_too_complex;  # undef = no begin/end
 
 509         if $set->max->is_infinite ||
 
 510            $set->min->is_infinite;
 
 513     my $next = $self->min;
 
 515         my $next1 = $span->min;
 
 516         $next = $next1 if $next1 && $next1 > $next;
 
 517         $next = $self->current( $next );
 
 519     my $last = $self->max;
 
 521         my $last1 = $span->max;
 
 522         $last = $last1 if $last1 && $last1 < $last;
 
 525         push @result, $next if !$span || $span->contains($next);
 
 526         $next = $self->next( $next );
 
 528     while $next && $next <= $last;
 
 533     my ($set1, $set2) = ( shift, shift );
 
 534     my $class = ref($set1);
 
 535     my $tmp = $class->empty_set();
 
 536     $set2 = $set2->as_set
 
 537         if $set2->can( 'as_set' );
 
 538     $set2 = $class->from_datetimes( dates => [ $set2, @_ ] ) 
 
 539         unless $set2->can( 'union' );
 
 540     $tmp->{set} = $set1->{set}->intersection( $set2->{set} );
 
 545     my ($set1, $set2) = ( shift, shift );
 
 546     my $class = ref($set1);
 
 547     $set2 = $set2->as_set
 
 548         if $set2->can( 'as_set' );
 
 549     unless ( $set2->can( 'union' ) )
 
 551         if ( $set1->{set}->_is_recurrence )
 
 555                 return 1 if $set1->current( $_ ) == $_;
 
 559         $set2 = $class->from_datetimes( dates => [ $set2, @_ ] )
 
 561     return $set1->{set}->intersects( $set2->{set} );
 
 565     my ($set1, $set2) = ( shift, shift );
 
 566     my $class = ref($set1);
 
 567     $set2 = $set2->as_set
 
 568         if $set2->can( 'as_set' );
 
 569     unless ( $set2->can( 'union' ) )
 
 571         if ( $set1->{set}->_is_recurrence )
 
 575                 return 0 unless $set1->current( $_ ) == $_;
 
 579         $set2 = $class->from_datetimes( dates => [ $set2, @_ ] ) 
 
 581     return $set1->{set}->contains( $set2->{set} );
 
 585     my ($set1, $set2) = ( shift, shift );
 
 586     my $class = ref($set1);
 
 587     my $tmp = $class->empty_set();
 
 588     $set2 = $set2->as_set
 
 589         if $set2->can( 'as_set' );
 
 590     $set2 = $class->from_datetimes( dates => [ $set2, @_ ] ) 
 
 591         unless $set2->can( 'union' );
 
 592     $tmp->{set} = $set1->{set}->union( $set2->{set} );
 
 593     bless $tmp, 'DateTime::SpanSet' 
 
 594         if $set2->isa('DateTime::Span') or $set2->isa('DateTime::SpanSet');
 
 599     my ($set1, $set2) = ( shift, shift );
 
 600     my $class = ref($set1);
 
 601     my $tmp = $class->empty_set();
 
 604         $set2 = $set2->as_set
 
 605             if $set2->can( 'as_set' );
 
 606         $set2 = $class->from_datetimes( dates => [ $set2, @_ ] ) 
 
 607             unless $set2->can( 'union' );
 
 608         # TODO: "compose complement";
 
 609         $tmp->{set} = $set1->{set}->complement( $set2->{set} );
 
 613         $tmp->{set} = $set1->{set}->complement;
 
 614         bless $tmp, 'DateTime::SpanSet';
 
 620     return _fix_datetime( $_[0]->{set}->min );
 
 624     return _fix_datetime( $_[0]->{set}->max );
 
 627 # returns a DateTime::Span
 
 629   my $set = $_[0]->{set}->span;
 
 630   my $self = bless { set => $set }, 'DateTime::Span';
 
 636     return undef unless ref( $self->{set} );
 
 640     $span = delete $args{span};
 
 641     $span = DateTime::Span->new( %args ) if %args;
 
 643     my $set = $self->clone;
 
 644     $set = $set->intersection( $span ) if $span;
 
 646     return $set->{set}->count
 
 647         unless $set->{set}->is_too_complex;
 
 650         if $set->max->is_infinite ||
 
 651            $set->min->is_infinite;
 
 654     my $iter = $set->iterator;
 
 655     $count++ while $iter->next;
 
 665 DateTime::Set - Datetime sets and set math
 
 672     $date1 = DateTime->new( year => 2002, month => 3, day => 11 );
 
 673     $set1 = DateTime::Set->from_datetimes( dates => [ $date1 ] );
 
 676     $date2 = DateTime->new( year => 2003, month => 4, day => 12 );
 
 677     $set2 = DateTime::Set->from_datetimes( dates => [ $date1, $date2 ] );
 
 678     #  set2 = 2002-03-11, and 2003-04-12
 
 680     $date3 = DateTime->new( year => 2003, month => 4, day => 1 );
 
 681     print $set2->next( $date3 )->ymd;      # 2003-04-12
 
 682     print $set2->previous( $date3 )->ymd;  # 2002-03-11
 
 683     print $set2->current( $date3 )->ymd;   # 2002-03-11
 
 684     print $set2->closest( $date3 )->ymd;   # 2003-04-12
 
 686     # a 'monthly' recurrence:
 
 687     $set = DateTime::Set->from_recurrence( 
 
 689             return $_[0] if $_[0]->is_infinite;
 
 690             return $_[0]->truncate( to => 'month' )->add( months => 1 )
 
 692         span => $date_span1,    # optional span
 
 695     $set = $set1->union( $set2 );         # like "OR", "insert", "both"
 
 696     $set = $set1->complement( $set2 );    # like "delete", "remove"
 
 697     $set = $set1->intersection( $set2 );  # like "AND", "while"
 
 698     $set = $set1->complement;             # like "NOT", "negate", "invert"
 
 700     if ( $set1->intersects( $set2 ) ) { ...  # like "touches", "interferes"
 
 701     if ( $set1->contains( $set2 ) ) { ...    # like "is-fully-inside"
 
 704     $date = $set1->min;           # first date of the set
 
 705     $date = $set1->max;           # last date of the set
 
 707     $iter = $set1->iterator;
 
 708     while ( $dt = $iter->next ) {
 
 714 DateTime::Set is a module for datetime sets.  It can be used to handle
 
 715 two different types of sets.
 
 717 The first is a fixed set of predefined datetime objects.  For example,
 
 718 if we wanted to create a set of datetimes containing the birthdays of
 
 719 people in our family for the current year.
 
 721 The second type of set that it can handle is one based on a
 
 722 recurrence, such as "every Wednesday", or "noon on the 15th day of
 
 723 every month".  This type of set can have fixed starting and ending
 
 724 datetimes, but neither is required.  So our "every Wednesday set"
 
 725 could be "every Wednesday from the beginning of time until the end of
 
 726 time", or "every Wednesday after 2003-03-05 until the end of time", or
 
 727 "every Wednesday between 2003-03-05 and 2004-01-07".
 
 729 This module also supports set math operations, so you do things like
 
 730 create a new set from the union or difference of two sets, check
 
 731 whether a datetime is a member of a given set, etc.
 
 733 This is different from a C<DateTime::Span>, which handles a continuous
 
 734 range as opposed to individual datetime points. There is also a module
 
 735 C<DateTime::SpanSet> to handle sets of spans.
 
 741 =item * from_datetimes
 
 743 Creates a new set from a list of datetimes.
 
 745    $dates = DateTime::Set->from_datetimes( dates => [ $dt1, $dt2, $dt3 ] );
 
 747 The datetimes can be objects from class C<DateTime>, or from a
 
 748 C<DateTime::Calendar::*> class.
 
 750 C<DateTime::Infinite::*> objects are not valid set members.
 
 752 =item * from_recurrence
 
 754 Creates a new set specified via a "recurrence" callback.
 
 756     $months = DateTime::Set->from_recurrence( 
 
 757         span => $dt_span_this_year,    # optional span
 
 759             return $_[0]->truncate( to => 'month' )->add( months => 1 ) 
 
 763 The C<span> parameter is optional. It must be a C<DateTime::Span> object.
 
 765 The span can also be specified using C<begin> / C<after> and C<before>
 
 766 / C<end> parameters, as in the C<DateTime::Span> constructor.  In this
 
 767 case, if there is a C<span> parameter it will be ignored.
 
 769     $months = DateTime::Set->from_recurrence(
 
 772             return $_[0]->truncate( to => 'month' )->add( months => 1 );
 
 776 The recurrence function will be passed a single parameter, a datetime
 
 777 object. The parameter can be an object from class C<DateTime>, or from
 
 778 one of the C<DateTime::Calendar::*> classes.  The parameter can also
 
 779 be a C<DateTime::Infinite::Future> or a C<DateTime::Infinite::Past>
 
 782 The recurrence must return the I<next> event after that object.  There
 
 783 is no guarantee as to what the returned object will be set to, only
 
 784 that it will be greater than the object passed to the recurrence.
 
 786 If there are no more datetimes after the given parameter, then the
 
 787 recurrence function should return C<DateTime::Infinite::Future>.
 
 789 It is ok to modify the parameter C<$_[0]> inside the recurrence
 
 790 function.  There are no side-effects.
 
 792 For example, if you wanted a recurrence that generated datetimes in
 
 793 increments of 30 seconds, it would look like this:
 
 795   sub every_30_seconds {
 
 797       if ( $dt->second < 30 ) {
 
 798           return $dt->truncate( to => 'minute' )->add( seconds => 30 );
 
 800           return $dt->truncate( to => 'minute' )->add( minutes => 1 );
 
 804 Note that this recurrence takes leap seconds into account.  Consider
 
 805 using C<truncate()> in this manner to avoid complicated arithmetic
 
 808 It is also possible to create a recurrence by specifying either or both
 
 809 of 'next' and 'previous' callbacks.
 
 811 The callbacks can return C<DateTime::Infinite::Future> and
 
 812 C<DateTime::Infinite::Past> objects, in order to define I<bounded
 
 813 recurrences>.  In this case, both 'next' and 'previous' callbacks must
 
 816     # "monthly from $dt until forever"
 
 818     my $months = DateTime::Set->from_recurrence(
 
 820             return $dt if $_[0] < $dt;
 
 821             $_[0]->truncate( to => 'month' );
 
 822             $_[0]->add( months => 1 );
 
 826             my $param = $_[0]->clone;
 
 827             $_[0]->truncate( to => 'month' );
 
 828             $_[0]->subtract( months => 1 ) if $_[0] == $param;
 
 829             return $_[0] if $_[0] >= $dt;
 
 830             return DateTime::Infinite::Past->new;
 
 834 Bounded recurrences are easier to write using C<span> parameters. See above.
 
 836 See also C<DateTime::Event::Recurrence> and the other
 
 837 C<DateTime::Event::*> factory modules for generating specialized
 
 838 recurrences, such as sunrise and sunset times, and holidays.
 
 842 Creates a new empty set.
 
 844     $set = DateTime::Set->empty_set;
 
 845     print "empty set" unless defined $set->max;
 
 849 This object method returns a replica of the given object.
 
 851 C<clone> is useful if you want to apply a transformation to a set,
 
 852 but you want to keep the previous value:
 
 854     $set2 = $set1->clone;
 
 855     $set2->add_duration( year => 1 );  # $set1 is unaltered
 
 857 =item * add_duration( $duration )
 
 859 This method adds the specified duration to every element of the set.
 
 861     $dt_dur = new DateTime::Duration( year => 1 );
 
 862     $set->add_duration( $dt_dur );
 
 864 The original set is modified. If you want to keep the old values use:
 
 866     $new_set = $set->clone->add_duration( $dt_dur );
 
 870 This method is syntactic sugar around the C<add_duration()> method.
 
 872     $meetings_2004 = $meetings_2003->clone->add( years => 1 );
 
 874 =item * subtract_duration( $duration_object )
 
 876 When given a C<DateTime::Duration> object, this method simply calls
 
 877 C<invert()> on that object and passes that new duration to the
 
 878 C<add_duration> method.
 
 880 =item * subtract( DateTime::Duration->new parameters )
 
 882 Like C<add()>, this is syntactic sugar for the C<subtract_duration()>
 
 885 =item * set_time_zone( $tz )
 
 887 This method will attempt to apply the C<set_time_zone> method to every 
 
 890 =item * set( locale => .. )
 
 892 This method can be used to change the C<locale> of a datetime set.
 
 898 The first and last C<DateTime> in the set.  These methods may return
 
 899 C<undef> if the set is empty.  It is also possible that these methods
 
 900 may return a C<DateTime::Infinite::Past> or
 
 901 C<DateTime::Infinite::Future> object.
 
 903 These methods return just a I<copy> of the actual boundary value.
 
 904 If you modify the result, the set will not be modified.
 
 908 Returns the total span of the set, as a C<DateTime::Span> object.
 
 910 =item * iterator / next / previous
 
 912 These methods can be used to iterate over the datetimes in a set.
 
 914     $iter = $set1->iterator;
 
 915     while ( $dt = $iter->next ) {
 
 920     $iter = $set1->iterator;
 
 921     while ( $dt = $iter->previous ) {
 
 925 The boundaries of the iterator can be limited by passing it a C<span>
 
 926 parameter.  This should be a C<DateTime::Span> object which delimits
 
 927 the iterator's boundaries.  Optionally, instead of passing an object,
 
 928 you can pass any parameters that would work for one of the
 
 929 C<DateTime::Span> class's constructors, and an object will be created
 
 932 Obviously, if the span you specify is not restricted both at the start
 
 933 and end, then your iterator may iterate forever, depending on the
 
 934 nature of your set.  User beware!
 
 936 The C<next()> or C<previous()> method will return C<undef> when there
 
 937 are no more datetimes in the iterator.
 
 941 Returns the set elements as a list of C<DateTime> objects.  Just as
 
 942 with the C<iterator()> method, the C<as_list()> method can be limited
 
 945   my @dt = $set->as_list( span => $span );
 
 947 Applying C<as_list()> to a large recurrence set is a very expensive
 
 948 operation, both in CPU time and in the memory used.  If you I<really>
 
 949 need to extract elements from a large set, you can limit the set with
 
 952     my @short_list = $large_set->as_list( span => $short_span );
 
 954 For I<infinite> sets, C<as_list()> will return C<undef>.  Please note
 
 955 that this is explicitly not an empty list, since an empty list is a
 
 956 valid return value for empty sets!
 
 960 Returns a count of C<DateTime> objects in the set.  Just as with the
 
 961 C<iterator()> method, the C<count()> method can be limited by a span.
 
 963   defined( my $n = $set->count) or die "can't count";
 
 965   my $n = $set->count( span => $span );
 
 966   die "can't count" unless defined $n;
 
 968 Applying C<count()> to a large recurrence set is a very expensive
 
 969 operation, both in CPU time and in the memory used.  If you I<really>
 
 970 need to count elements from a large set, you can limit the set with a
 
 973     my $count = $large_set->count( span => $short_span );
 
 975 For I<infinite> sets, C<count()> will return C<undef>.  Please note
 
 976 that this is explicitly not a scalar zero, since a zero count is a
 
 977 valid return value for empty sets!
 
 985 These set operation methods can accept a C<DateTime> list, a
 
 986 C<DateTime::Set>, a C<DateTime::Span>, or a C<DateTime::SpanSet>
 
 987 object as an argument.
 
 989     $set = $set1->union( $set2 );         # like "OR", "insert", "both"
 
 990     $set = $set1->complement( $set2 );    # like "delete", "remove"
 
 991     $set = $set1->intersection( $set2 );  # like "AND", "while"
 
 992     $set = $set1->complement;             # like "NOT", "negate", "invert"
 
 994 The C<union> of a C<DateTime::Set> with a C<DateTime::Span> or a
 
 995 C<DateTime::SpanSet> object returns a C<DateTime::SpanSet> object.
 
 997 If C<complement> is called without any arguments, then the result is a
 
 998 C<DateTime::SpanSet> object representing the spans between each of the
 
 999 set's elements.  If complement is given an argument, then the return
 
1000 value is a C<DateTime::Set> object representing the I<set difference>
 
1003 All other operations will always return a C<DateTime::Set>.
 
1009 These set operations result in a boolean value.
 
1011     if ( $set1->intersects( $set2 ) ) { ...  # like "touches", "interferes"
 
1012     if ( $set1->contains( $dt ) ) { ...    # like "is-fully-inside"
 
1014 These methods can accept a C<DateTime> list, a C<DateTime::Set>, a
 
1015 C<DateTime::Span>, or a C<DateTime::SpanSet> object as an argument.
 
1025   my $dt = $set->next( $dt );
 
1026   my $dt = $set->previous( $dt );
 
1027   my $dt = $set->current( $dt );
 
1028   my $dt = $set->closest( $dt );
 
1030 These methods are used to find a set member relative to a given
 
1033 The C<current()> method returns C<$dt> if $dt is an event, otherwise
 
1034 it returns the previous event.
 
1036 The C<closest()> method returns C<$dt> if $dt is an event, otherwise
 
1037 it returns the closest event (previous or next).
 
1039 All of these methods may return C<undef> if there is no matching
 
1040 datetime in the set.
 
1042 These methods will try to set the returned value to the same time zone
 
1043 as the argument, unless the argument has a 'floating' time zone.
 
1045 =item * map ( sub { ... } )
 
1047     # example: remove the hour:minute:second information
 
1050             return $_->truncate( to => day );
 
1054     # example: postpone or antecipate events which 
 
1055     #          match datetimes within another set
 
1058             return $_->add( days => 1 ) while $holidays->contains( $_ );
 
1062 This method is the "set" version of Perl "map".
 
1064 It evaluates a subroutine for each element of the set (locally setting
 
1065 "$_" to each datetime) and returns the set composed of the results of
 
1066 each such evaluation.
 
1068 Like Perl "map", each element of the set may produce zero, one, or
 
1069 more elements in the returned value.
 
1071 Unlike Perl "map", changing "$_" does not change the original
 
1072 set. This means that calling map in void context has no effect.
 
1074 The callback subroutine may be called later in the program, due to
 
1075 lazy evaluation.  So don't count on subroutine side-effects. For
 
1076 example, a C<print> inside the subroutine may happen later than you
 
1079 The callback return value is expected to be within the span of the
 
1080 C<previous> and the C<next> element in the original set.  This is a
 
1081 limitation of the backtracking algorithm used in the C<Set::Infinite>
 
1084 For example: given the set C<[ 2001, 2010, 2015 ]>, the callback
 
1085 result for the value C<2010> is expected to be within the span C<[
 
1088 =item * grep ( sub { ... } )
 
1090     # example: filter out any sundays
 
1093             return ( $_->day_of_week != 7 );
 
1097 This method is the "set" version of Perl "grep".
 
1099 It evaluates a subroutine for each element of the set (locally setting
 
1100 "$_" to each datetime) and returns the set consisting of those
 
1101 elements for which the expression evaluated to true.
 
1103 Unlike Perl "grep", changing "$_" does not change the original
 
1104 set. This means that calling grep in void context has no effect.
 
1106 Changing "$_" does change the resulting set.
 
1108 The callback subroutine may be called later in the program, due to
 
1109 lazy evaluation.  So don't count on subroutine side-effects. For
 
1110 example, a C<print> inside the subroutine may happen later than you
 
1113 =item * iterate ( sub { ... } )
 
1115 I<deprecated method - please use "map" or "grep" instead.>
 
1121 Support is offered through the C<datetime@perl.org> mailing list.
 
1123 Please report bugs using rt.cpan.org
 
1127 Flavio Soibelmann Glock <fglock@pucrs.br>
 
1129 The API was developed together with Dave Rolsky and the DateTime
 
1134 Copyright (c) 2003-2006 Flavio Soibelmann Glock. All rights reserved.
 
1135 This program is free software; you can distribute it and/or modify it
 
1136 under the same terms as Perl itself.
 
1138 The full text of the license can be found in the LICENSE file included
 
1145 For details on the Perl DateTime Suite project please see
 
1146 L<http://datetime.perl.org>.