1DateTime::Set(3) User Contributed Perl Documentation DateTime::Set(3)
2
3
4
6 DateTime::Set - Datetime sets and set math
7
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
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
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 "begin" / "after" and "before"
103 / "end" 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 · clone
186
187 This object method returns a replica of the given object.
188
189 "clone" is useful if you want to apply a transformation to a set,
190 but you want to keep the previous value:
191
192 $set2 = $set1->clone;
193 $set2->add_duration( year => 1 ); # $set1 is unaltered
194
195 · add_duration( $duration )
196
197 This method adds the specified duration to every element of the
198 set.
199
200 $dt_dur = new DateTime::Duration( year => 1 );
201 $set->add_duration( $dt_dur );
202
203 The original set is modified. If you want to keep the old values
204 use:
205
206 $new_set = $set->clone->add_duration( $dt_dur );
207
208 · add
209
210 This method is syntactic sugar around the "add_duration()" method.
211
212 $meetings_2004 = $meetings_2003->clone->add( years => 1 );
213
214 · subtract_duration( $duration_object )
215
216 When given a "DateTime::Duration" object, this method simply calls
217 "invert()" on that object and passes that new duration to the
218 "add_duration" method.
219
220 · subtract( DateTime::Duration->new parameters )
221
222 Like "add()", this is syntactic sugar for the "subtract_duration()"
223 method.
224
225 · set_time_zone( $tz )
226
227 This method will attempt to apply the "set_time_zone" method to
228 every datetime in the set.
229
230 · set( locale => .. )
231
232 This method can be used to change the "locale" of a datetime set.
233
234 · min
235
236 · max
237
238 The first and last "DateTime" in the set. These methods may return
239 "undef" if the set is empty. It is also possible that these
240 methods may return a "DateTime::Infinite::Past" or
241 "DateTime::Infinite::Future" object.
242
243 These methods return just a copy of the actual boundary value. If
244 you modify the result, the set will not be modified.
245
246 · span
247
248 Returns the total span of the set, as a "DateTime::Span" object.
249
250 · iterator / next / previous
251
252 These methods can be used to iterate over the datetimes in a set.
253
254 $iter = $set1->iterator;
255 while ( $dt = $iter->next ) {
256 print $dt->ymd;
257 }
258
259 # iterate backwards
260 $iter = $set1->iterator;
261 while ( $dt = $iter->previous ) {
262 print $dt->ymd;
263 }
264
265 The boundaries of the iterator can be limited by passing it a
266 "span" parameter. This should be a "DateTime::Span" object which
267 delimits the iterator's boundaries. Optionally, instead of passing
268 an object, you can pass any parameters that would work for one of
269 the "DateTime::Span" class's constructors, and an object will be
270 created for you.
271
272 Obviously, if the span you specify is not restricted both at the
273 start and end, then your iterator may iterate forever, depending on
274 the nature of your set. User beware!
275
276 The "next()" or "previous()" method will return "undef" when there
277 are no more datetimes in the iterator.
278
279 · as_list
280
281 Returns the set elements as a list of "DateTime" objects. Just as
282 with the "iterator()" method, the "as_list()" method can be limited
283 by a span.
284
285 my @dt = $set->as_list( span => $span );
286
287 Applying "as_list()" to a large recurrence set is a very expensive
288 operation, both in CPU time and in the memory used. If you really
289 need to extract elements from a large set, you can limit the set
290 with a shorter span:
291
292 my @short_list = $large_set->as_list( span => $short_span );
293
294 For infinite sets, "as_list()" will return "undef". Please note
295 that this is explicitly not an empty list, since an empty list is a
296 valid return value for empty sets!
297
298 · count
299
300 Returns a count of "DateTime" objects in the set. Just as with the
301 "iterator()" method, the "count()" method can be limited by a span.
302
303 defined( my $n = $set->count) or die "can't count";
304
305 my $n = $set->count( span => $span );
306 die "can't count" unless defined $n;
307
308 Applying "count()" to a large recurrence set is a very expensive
309 operation, both in CPU time and in the memory used. If you really
310 need to count elements from a large set, you can limit the set with
311 a shorter span:
312
313 my $count = $large_set->count( span => $short_span );
314
315 For infinite sets, "count()" will return "undef". Please note that
316 this is explicitly not a scalar zero, since a zero count is a valid
317 return value for empty sets!
318
319 · union
320
321 · intersection
322
323 · complement
324
325 These set operation methods can accept a "DateTime" list, a
326 "DateTime::Set", a "DateTime::Span", or a "DateTime::SpanSet"
327 object as an argument.
328
329 $set = $set1->union( $set2 ); # like "OR", "insert", "both"
330 $set = $set1->complement( $set2 ); # like "delete", "remove"
331 $set = $set1->intersection( $set2 ); # like "AND", "while"
332 $set = $set1->complement; # like "NOT", "negate", "invert"
333
334 The "union" of a "DateTime::Set" with a "DateTime::Span" or a
335 "DateTime::SpanSet" object returns a "DateTime::SpanSet" object.
336
337 If "complement" is called without any arguments, then the result is
338 a "DateTime::SpanSet" object representing the spans between each of
339 the set's elements. If complement is given an argument, then the
340 return value is a "DateTime::Set" object representing the set
341 difference between the sets.
342
343 All other operations will always return a "DateTime::Set".
344
345 · intersects
346
347 · contains
348
349 These set operations result in a boolean value.
350
351 if ( $set1->intersects( $set2 ) ) { ... # like "touches", "interferes"
352 if ( $set1->contains( $dt ) ) { ... # like "is-fully-inside"
353
354 These methods can accept a "DateTime" list, a "DateTime::Set", a
355 "DateTime::Span", or a "DateTime::SpanSet" object as an argument.
356
357 · previous
358
359 · next
360
361 · current
362
363 · closest
364
365 my $dt = $set->next( $dt );
366 my $dt = $set->previous( $dt );
367 my $dt = $set->current( $dt );
368 my $dt = $set->closest( $dt );
369
370 These methods are used to find a set member relative to a given
371 datetime.
372
373 The "current()" method returns $dt if $dt is an event, otherwise it
374 returns the previous event.
375
376 The "closest()" method returns $dt if $dt is an event, otherwise it
377 returns the closest event (previous or next).
378
379 All of these methods may return "undef" if there is no matching
380 datetime in the set.
381
382 These methods will try to set the returned value to the same time
383 zone as the argument, unless the argument has a 'floating' time
384 zone.
385
386 · map ( sub { ... } )
387
388 # example: remove the hour:minute:second information
389 $set = $set2->map(
390 sub {
391 return $_->truncate( to => day );
392 }
393 );
394
395 # example: postpone or antecipate events which
396 # match datetimes within another set
397 $set = $set2->map(
398 sub {
399 return $_->add( days => 1 ) while $holidays->contains( $_ );
400 }
401 );
402
403 This method is the "set" version of Perl "map".
404
405 It evaluates a subroutine for each element of the set (locally
406 setting "$_" to each datetime) and returns the set composed of the
407 results of each such evaluation.
408
409 Like Perl "map", each element of the set may produce zero, one, or
410 more elements in the returned value.
411
412 Unlike Perl "map", changing "$_" does not change the original set.
413 This means that calling map in void context has no effect.
414
415 The callback subroutine may be called later in the program, due to
416 lazy evaluation. So don't count on subroutine side-effects. For
417 example, a "print" inside the subroutine may happen later than you
418 expect.
419
420 The callback return value is expected to be within the span of the
421 "previous" and the "next" element in the original set. This is a
422 limitation of the backtracking algorithm used in the
423 "Set::Infinite" library.
424
425 For example: given the set "[ 2001, 2010, 2015 ]", the callback
426 result for the value 2010 is expected to be within the span "[ 2001
427 .. 2015 ]".
428
429 · grep ( sub { ... } )
430
431 # example: filter out any sundays
432 $set = $set2->grep(
433 sub {
434 return ( $_->day_of_week != 7 );
435 }
436 );
437
438 This method is the "set" version of Perl "grep".
439
440 It evaluates a subroutine for each element of the set (locally
441 setting "$_" to each datetime) and returns the set consisting of
442 those elements for which the expression evaluated to true.
443
444 Unlike Perl "grep", changing "$_" does not change the original set.
445 This means that calling grep in void context has no effect.
446
447 Changing "$_" does change the resulting set.
448
449 The callback subroutine may be called later in the program, due to
450 lazy evaluation. So don't count on subroutine side-effects. For
451 example, a "print" inside the subroutine may happen later than you
452 expect.
453
454 · iterate ( sub { ... } )
455
456 deprecated method - please use "map" or "grep" instead.
457
459 Support is offered through the "datetime@perl.org" mailing list.
460
461 Please report bugs using rt.cpan.org
462
464 Flavio Soibelmann Glock <fglock@pucrs.br>
465
466 The API was developed together with Dave Rolsky and the DateTime
467 Community.
468
470 Copyright (c) 2003-2006 Flavio Soibelmann Glock. All rights reserved.
471 This program is free software; you can distribute it and/or modify it
472 under the same terms as Perl itself.
473
474 The full text of the license can be found in the LICENSE file included
475 with this module.
476
478 Set::Infinite
479
480 For details on the Perl DateTime Suite project please see
481 <http://datetime.perl.org>.
482
483
484
485perl v5.12.0 2010-05-14 DateTime::Set(3)