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>.