1DateTime::Set(3)      User Contributed Perl Documentation     DateTime::Set(3)
2
3
4

NAME

6       DateTime::Set - Datetime sets and set math
7

SYNOPSIS

9           use DateTime;
10           use DateTime::Set;
11
12           $date1 = DateTime->new( year => 2002, month => 3, day => 11 );
13           $set1 = DateTime::Set->from_datetimes( dates => [ $date1 ] );
14           #  set1 = 2002-03-11
15
16           $date2 = DateTime->new( year => 2003, month => 4, day => 12 );
17           $set2 = DateTime::Set->from_datetimes( dates => [ $date1, $date2 ] );
18           #  set2 = 2002-03-11, and 2003-04-12
19
20           $date3 = DateTime->new( year => 2003, month => 4, day => 1 );
21           print $set2->next( $date3 )->ymd;      # 2003-04-12
22           print $set2->previous( $date3 )->ymd;  # 2002-03-11
23           print $set2->current( $date3 )->ymd;   # 2002-03-11
24           print $set2->closest( $date3 )->ymd;   # 2003-04-12
25
26           # a 'monthly' recurrence:
27           $set = DateTime::Set->from_recurrence(
28               recurrence => sub {
29                   return $_[0] if $_[0]->is_infinite;
30                   return $_[0]->truncate( to => 'month' )->add( months => 1 )
31               },
32               span => $date_span1,    # optional span
33           );
34
35           $set = $set1->union( $set2 );         # like "OR", "insert", "both"
36           $set = $set1->complement( $set2 );    # like "delete", "remove"
37           $set = $set1->intersection( $set2 );  # like "AND", "while"
38           $set = $set1->complement;             # like "NOT", "negate", "invert"
39
40           if ( $set1->intersects( $set2 ) ) { ...  # like "touches", "interferes"
41           if ( $set1->contains( $set2 ) ) { ...    # like "is-fully-inside"
42
43           # data extraction
44           $date = $set1->min;           # first date of the set
45           $date = $set1->max;           # last date of the set
46
47           $iter = $set1->iterator;
48           while ( $dt = $iter->next ) {
49               print $dt->ymd;
50           };
51

DESCRIPTION

53       DateTime::Set is a module for datetime sets.  It can be used to handle
54       two different types of sets.
55
56       The first is a fixed set of predefined datetime objects.  For example,
57       if we wanted to create a set of datetimes containing the birthdays of
58       people in our family for the current year.
59
60       The second type of set that it can handle is one based on a recurrence,
61       such as "every Wednesday", or "noon on the 15th day of every month".
62       This type of set can have fixed starting and ending datetimes, but
63       neither is required.  So our "every Wednesday set" could be "every
64       Wednesday from the beginning of time until the end of time", or "every
65       Wednesday after 2003-03-05 until the end of time", or "every Wednesday
66       between 2003-03-05 and 2004-01-07".
67
68       This module also supports set math operations, so you do things like
69       create a new set from the union or difference of two sets, check
70       whether a datetime is a member of a given set, etc.
71
72       This is different from a "DateTime::Span", which handles a continuous
73       range as opposed to individual datetime points. There is also a module
74       "DateTime::SpanSet" to handle sets of spans.
75

METHODS

77       •   from_datetimes
78
79           Creates a new set from a list of datetimes.
80
81              $dates = DateTime::Set->from_datetimes( dates => [ $dt1, $dt2, $dt3 ] );
82
83           The datetimes can be objects from class "DateTime", or from a
84           "DateTime::Calendar::*" class.
85
86           "DateTime::Infinite::*" objects are not valid set members.
87
88       •   from_recurrence
89
90           Creates a new set specified via a "recurrence" callback.
91
92               $months = DateTime::Set->from_recurrence(
93                   span => $dt_span_this_year,    # optional span
94                   recurrence => sub {
95                       return $_[0]->truncate( to => 'month' )->add( months => 1 )
96                   },
97               );
98
99           The "span" parameter is optional. It must be a "DateTime::Span"
100           object.
101
102           The span can also be specified using "start" / "after" and "end" /
103           "before" parameters, as in the "DateTime::Span" constructor.  In
104           this case, if there is a "span" parameter it will be ignored.
105
106               $months = DateTime::Set->from_recurrence(
107                   after => $dt_now,
108                   recurrence => sub {
109                       return $_[0]->truncate( to => 'month' )->add( months => 1 );
110                   },
111               );
112
113           The recurrence function will be passed a single parameter, a
114           datetime object. The parameter can be an object from class
115           "DateTime", or from one of the "DateTime::Calendar::*" classes.
116           The parameter can also be a "DateTime::Infinite::Future" or a
117           "DateTime::Infinite::Past" object.
118
119           The recurrence must return the next event after that object.  There
120           is no guarantee as to what the returned object will be set to, only
121           that it will be greater than the object passed to the recurrence.
122
123           If there are no more datetimes after the given parameter, then the
124           recurrence function should return "DateTime::Infinite::Future".
125
126           It is ok to modify the parameter $_[0] inside the recurrence
127           function.  There are no side-effects.
128
129           For example, if you wanted a recurrence that generated datetimes in
130           increments of 30 seconds, it would look like this:
131
132             sub every_30_seconds {
133                 my $dt = shift;
134                 if ( $dt->second < 30 ) {
135                     return $dt->truncate( to => 'minute' )->add( seconds => 30 );
136                 } else {
137                     return $dt->truncate( to => 'minute' )->add( minutes => 1 );
138                 }
139             }
140
141           Note that this recurrence takes leap seconds into account.
142           Consider using "truncate()" in this manner to avoid complicated
143           arithmetic problems!
144
145           It is also possible to create a recurrence by specifying either or
146           both of 'next' and 'previous' callbacks.
147
148           The callbacks can return "DateTime::Infinite::Future" and
149           "DateTime::Infinite::Past" objects, in order to define bounded
150           recurrences.  In this case, both 'next' and 'previous' callbacks
151           must be defined:
152
153               # "monthly from $dt until forever"
154
155               my $months = DateTime::Set->from_recurrence(
156                   next => sub {
157                       return $dt if $_[0] < $dt;
158                       $_[0]->truncate( to => 'month' );
159                       $_[0]->add( months => 1 );
160                       return $_[0];
161                   },
162                   previous => sub {
163                       my $param = $_[0]->clone;
164                       $_[0]->truncate( to => 'month' );
165                       $_[0]->subtract( months => 1 ) if $_[0] == $param;
166                       return $_[0] if $_[0] >= $dt;
167                       return DateTime::Infinite::Past->new;
168                   },
169               );
170
171           Bounded recurrences are easier to write using "span" parameters.
172           See above.
173
174           See also "DateTime::Event::Recurrence" and the other
175           "DateTime::Event::*" factory modules for generating specialized
176           recurrences, such as sunrise and sunset times, and holidays.
177
178       •   empty_set
179
180           Creates a new empty set.
181
182               $set = DateTime::Set->empty_set;
183               print "empty set" unless defined $set->max;
184
185       •   is_empty_set
186
187           Returns true is the set is empty; false otherwise.
188
189               print "nothing" if $set->is_empty_set;
190
191       •   clone
192
193           This object method returns a replica of the given object.
194
195           "clone" is useful if you want to apply a transformation to a set,
196           but you want to keep the previous value:
197
198               $set2 = $set1->clone;
199               $set2->add_duration( year => 1 );  # $set1 is unaltered
200
201       •   add_duration( $duration )
202
203           This method adds the specified duration to every element of the
204           set.
205
206               $dt_dur = new DateTime::Duration( year => 1 );
207               $set->add_duration( $dt_dur );
208
209           The original set is modified. If you want to keep the old values
210           use:
211
212               $new_set = $set->clone->add_duration( $dt_dur );
213
214       •   add
215
216           This method is syntactic sugar around the "add_duration()" method.
217
218               $meetings_2004 = $meetings_2003->clone->add( years => 1 );
219
220       •   subtract_duration( $duration_object )
221
222           When given a "DateTime::Duration" object, this method simply calls
223           "invert()" on that object and passes that new duration to the
224           "add_duration" method.
225
226       •   subtract( DateTime::Duration->new parameters )
227
228           Like "add()", this is syntactic sugar for the "subtract_duration()"
229           method.
230
231       •   set_time_zone( $tz )
232
233           This method will attempt to apply the "set_time_zone" method to
234           every datetime in the set.
235
236       •   set( locale => .. )
237
238           This method can be used to change the "locale" of a datetime set.
239
240       •   start, min
241
242       •   end, max
243
244           The first and last "DateTime" in the set.
245
246           These methods may return "undef" if the set is empty.
247
248           It is also possible that these methods may return a
249           "DateTime::Infinite::Past" or "DateTime::Infinite::Future" object.
250
251           These methods return just a copy of the actual value.  If you
252           modify the result, the set will not be modified.
253
254       •   span
255
256           Returns the total span of the set, as a "DateTime::Span" object.
257
258       •   iterator / next / previous
259
260           These methods can be used to iterate over the datetimes in a set.
261
262               $iter = $set1->iterator;
263               while ( $dt = $iter->next ) {
264                   print $dt->ymd;
265               }
266
267               # iterate backwards
268               $iter = $set1->iterator;
269               while ( $dt = $iter->previous ) {
270                   print $dt->ymd;
271               }
272
273           The boundaries of the iterator can be limited by passing it a
274           "span" parameter.  This should be a "DateTime::Span" object which
275           delimits the iterator's boundaries.  Optionally, instead of passing
276           an object, you can pass any parameters that would work for one of
277           the "DateTime::Span" class's constructors, and an object will be
278           created for you.
279
280           Obviously, if the span you specify is not restricted both at the
281           start and end, then your iterator may iterate forever, depending on
282           the nature of your set.  User beware!
283
284           The "next()" or "previous()" method will return "undef" when there
285           are no more datetimes in the iterator.
286
287       •   as_list
288
289           Returns the set elements as a list of "DateTime" objects.  Just as
290           with the "iterator()" method, the "as_list()" method can be limited
291           by a span.
292
293             my @dt = $set->as_list( span => $span );
294
295           Applying "as_list()" to a large recurrence set is a very expensive
296           operation, both in CPU time and in the memory used.  If you really
297           need to extract elements from a large set, you can limit the set
298           with a shorter span:
299
300               my @short_list = $large_set->as_list( span => $short_span );
301
302           For infinite sets, "as_list()" will return "undef".  Please note
303           that this is explicitly not an empty list, since an empty list is a
304           valid return value for empty sets!
305
306       •   count
307
308           Returns a count of "DateTime" objects in the set.  Just as with the
309           "iterator()" method, the "count()" method can be limited by a span.
310
311             defined( my $n = $set->count) or die "can't count";
312
313             my $n = $set->count( span => $span );
314             die "can't count" unless defined $n;
315
316           Applying "count()" to a large recurrence set is a very expensive
317           operation, both in CPU time and in the memory used.  If you really
318           need to count elements from a large set, you can limit the set with
319           a shorter span:
320
321               my $count = $large_set->count( span => $short_span );
322
323           For infinite sets, "count()" will return "undef".  Please note that
324           this is explicitly not a scalar zero, since a zero count is a valid
325           return value for empty sets!
326
327       •   union
328
329       •   intersection
330
331       •   complement
332
333           These set operation methods can accept a "DateTime" list, a
334           "DateTime::Set", a "DateTime::Span", or a "DateTime::SpanSet"
335           object as an argument.
336
337               $set = $set1->union( $set2 );         # like "OR", "insert", "both"
338               $set = $set1->complement( $set2 );    # like "delete", "remove"
339               $set = $set1->intersection( $set2 );  # like "AND", "while"
340               $set = $set1->complement;             # like "NOT", "negate", "invert"
341
342           The "union" of a "DateTime::Set" with a "DateTime::Span" or a
343           "DateTime::SpanSet" object returns a "DateTime::SpanSet" object.
344
345           If "complement" is called without any arguments, then the result is
346           a "DateTime::SpanSet" object representing the spans between each of
347           the set's elements.  If complement is given an argument, then the
348           return value is a "DateTime::Set" object representing the set
349           difference between the sets.
350
351           All other operations will always return a "DateTime::Set".
352
353       •   intersects
354
355       •   contains
356
357           These set operations result in a boolean value.
358
359               if ( $set1->intersects( $set2 ) ) { ...  # like "touches", "interferes"
360               if ( $set1->contains( $dt ) ) { ...    # like "is-fully-inside"
361
362           These methods can accept a "DateTime" list, a "DateTime::Set", a
363           "DateTime::Span", or a "DateTime::SpanSet" object as an argument.
364
365           intersects() returns 1 for true, and 0 for false. In a few cases
366           the algorithm can't decide if the sets intersect at all, and
367           intersects() will return "undef".
368
369       •   previous
370
371       •   next
372
373       •   current
374
375       •   closest
376
377             my $dt = $set->next( $dt );
378             my $dt = $set->previous( $dt );
379             my $dt = $set->current( $dt );
380             my $dt = $set->closest( $dt );
381
382           These methods are used to find a set member relative to a given
383           datetime.
384
385           The "current()" method returns $dt if $dt is an event, otherwise it
386           returns the previous event.
387
388           The "closest()" method returns $dt if $dt is an event, otherwise it
389           returns the closest event (previous or next).
390
391           All of these methods may return "undef" if there is no matching
392           datetime in the set.
393
394           These methods will try to set the returned value to the same time
395           zone as the argument, unless the argument has a 'floating' time
396           zone.
397
398       •   map ( sub { ... } )
399
400               # example: remove the hour:minute:second information
401               $set = $set2->map(
402                   sub {
403                       return $_->truncate( to => day );
404                   }
405               );
406
407               # example: postpone or antecipate events which
408               #          match datetimes within another set
409               $set = $set2->map(
410                   sub {
411                       return $_->add( days => 1 ) while $holidays->contains( $_ );
412                   }
413               );
414
415           This method is the "set" version of Perl "map".
416
417           It evaluates a subroutine for each element of the set (locally
418           setting "$_" to each datetime) and returns the set composed of the
419           results of each such evaluation.
420
421           Like Perl "map", each element of the set may produce zero, one, or
422           more elements in the returned value.
423
424           Unlike Perl "map", changing "$_" does not change the original set.
425           This means that calling map in void context has no effect.
426
427           The callback subroutine may be called later in the program, due to
428           lazy evaluation.  So don't count on subroutine side-effects. For
429           example, a "print" inside the subroutine may happen later than you
430           expect.
431
432           The callback return value is expected to be within the span of the
433           "previous" and the "next" element in the original set.  This is a
434           limitation of the backtracking algorithm used in the
435           "Set::Infinite" library.
436
437           For example: given the set "[ 2001, 2010, 2015 ]", the callback
438           result for the value 2010 is expected to be within the span "[ 2001
439           .. 2015 ]".
440
441       •   grep ( sub { ... } )
442
443               # example: filter out any sundays
444               $set = $set2->grep(
445                   sub {
446                       return ( $_->day_of_week != 7 );
447                   }
448               );
449
450           This method is the "set" version of Perl "grep".
451
452           It evaluates a subroutine for each element of the set (locally
453           setting "$_" to each datetime) and returns the set consisting of
454           those elements for which the expression evaluated to true.
455
456           Unlike Perl "grep", changing "$_" does not change the original set.
457           This means that calling grep in void context has no effect.
458
459           Changing "$_" does change the resulting set.
460
461           The callback subroutine may be called later in the program, due to
462           lazy evaluation.  So don't count on subroutine side-effects. For
463           example, a "print" inside the subroutine may happen later than you
464           expect.
465
466       •   iterate ( sub { ... } )
467
468           deprecated method - please use "map" or "grep" instead.
469

SUPPORT

471       Support is offered through the "datetime@perl.org" mailing list.
472
473       Please report bugs using rt.cpan.org
474

AUTHOR

476       Flavio Soibelmann Glock <fglock@gmail.com>
477
478       The API was developed together with Dave Rolsky and the DateTime
479       Community.
480
482       Copyright (c) 2003-2006 Flavio Soibelmann Glock. All rights reserved.
483       This program is free software; you can distribute it and/or modify it
484       under the same terms as Perl itself.
485
486       The full text of the license can be found in the LICENSE file included
487       with this module.
488

SEE ALSO

490       Set::Infinite
491
492       For details on the Perl DateTime Suite project please see
493       <http://datetime.perl.org>.
494
495
496
497perl v5.34.0                      2022-01-21                  DateTime::Set(3)
Impressum