Filename | /usr/share/perl5/DateTime/SpanSet.pm |
Statements | Executed 19 statements in 3.13ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 11µs | 21µs | BEGIN@7 | DateTime::SpanSet::
1 | 1 | 1 | 10µs | 35µs | BEGIN@12 | DateTime::SpanSet::
1 | 1 | 1 | 9µs | 9µs | BEGIN@10 | DateTime::SpanSet::
1 | 1 | 1 | 7µs | 41µs | BEGIN@16 | DateTime::SpanSet::
1 | 1 | 1 | 7µs | 40µs | BEGIN@13 | DateTime::SpanSet::
1 | 1 | 1 | 6µs | 22µs | BEGIN@14 | DateTime::SpanSet::
1 | 1 | 1 | 6µs | 26µs | BEGIN@17 | DateTime::SpanSet::
1 | 1 | 1 | 4µs | 4µs | BEGIN@9 | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | __ANON__[:31] | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | __ANON__[:49] | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | __ANON__[:66] | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | __ANON__[:82] | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | __ANON__[:96] | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | as_list | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | clone | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | closest | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | complement | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | contains | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | current | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | duration | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | empty_set | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | end_set | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | from_set_and_duration | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | from_sets | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | from_spans | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | grep | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | intersected_spans | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | intersection | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | intersects | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | is_empty_set | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | iterate | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | iterator | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | map | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | max | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | min | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | next | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | previous | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | set_time_zone | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | span | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | start_set | DateTime::SpanSet::
0 | 0 | 0 | 0s | 0s | union | DateTime::SpanSet::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # Copyright (c) 2003 Flavio Soibelmann Glock. All rights reserved. | ||||
2 | # This program is free software; you can redistribute it and/or | ||||
3 | # modify it under the same terms as Perl itself. | ||||
4 | |||||
5 | package DateTime::SpanSet; | ||||
6 | |||||
7 | 2 | 22µs | 2 | 31µs | # spent 21µs (11+10) within DateTime::SpanSet::BEGIN@7 which was called:
# once (11µs+10µs) by DateTime::Span::BEGIN@10 at line 7 # spent 21µs making 1 call to DateTime::SpanSet::BEGIN@7
# spent 10µs making 1 call to strict::import |
8 | |||||
9 | 2 | 22µs | 1 | 4µs | # spent 4µs within DateTime::SpanSet::BEGIN@9 which was called:
# once (4µs+0s) by DateTime::Span::BEGIN@10 at line 9 # spent 4µs making 1 call to DateTime::SpanSet::BEGIN@9 |
10 | 2 | 24µs | 1 | 9µs | # spent 9µs within DateTime::SpanSet::BEGIN@10 which was called:
# once (9µs+0s) by DateTime::Span::BEGIN@10 at line 10 # spent 9µs making 1 call to DateTime::SpanSet::BEGIN@10 |
11 | |||||
12 | 2 | 26µs | 2 | 61µs | # spent 35µs (10+26) within DateTime::SpanSet::BEGIN@12 which was called:
# once (10µs+26µs) by DateTime::Span::BEGIN@10 at line 12 # spent 35µs making 1 call to DateTime::SpanSet::BEGIN@12
# spent 26µs making 1 call to Exporter::import |
13 | 2 | 22µs | 2 | 74µs | # spent 40µs (7+34) within DateTime::SpanSet::BEGIN@13 which was called:
# once (7µs+34µs) by DateTime::Span::BEGIN@10 at line 13 # spent 40µs making 1 call to DateTime::SpanSet::BEGIN@13
# spent 34µs making 1 call to Exporter::import |
14 | 2 | 30µs | 2 | 38µs | # spent 22µs (6+16) within DateTime::SpanSet::BEGIN@14 which was called:
# once (6µs+16µs) by DateTime::Span::BEGIN@10 at line 14 # spent 22µs making 1 call to DateTime::SpanSet::BEGIN@14
# spent 16µs making 1 call to vars::import |
15 | |||||
16 | 2 | 33µs | 2 | 75µs | # spent 41µs (7+34) within DateTime::SpanSet::BEGIN@16 which was called:
# once (7µs+34µs) by DateTime::Span::BEGIN@10 at line 16 # spent 41µs making 1 call to DateTime::SpanSet::BEGIN@16
# spent 34µs making 1 call to constant::import |
17 | 2 | 2.95ms | 2 | 48µs | # spent 26µs (6+21) within DateTime::SpanSet::BEGIN@17 which was called:
# once (6µs+21µs) by DateTime::Span::BEGIN@10 at line 17 # spent 26µs making 1 call to DateTime::SpanSet::BEGIN@17
# spent 21µs making 1 call to constant::import |
18 | 1 | 200ns | $VERSION = $DateTime::Set::VERSION; | ||
19 | |||||
20 | sub iterate { | ||||
21 | my ( $self, $callback ) = @_; | ||||
22 | my $class = ref( $self ); | ||||
23 | my $return = $class->empty_set; | ||||
24 | $return->{set} = $self->{set}->iterate( | ||||
25 | sub { | ||||
26 | my $span = bless { set => $_[0] }, 'DateTime::Span'; | ||||
27 | $callback->( $span->clone ); | ||||
28 | $span = $span->{set} | ||||
29 | if UNIVERSAL::can( $span, 'union' ); | ||||
30 | return $span; | ||||
31 | } | ||||
32 | ); | ||||
33 | $return; | ||||
34 | } | ||||
35 | |||||
36 | sub map { | ||||
37 | my ( $self, $callback ) = @_; | ||||
38 | my $class = ref( $self ); | ||||
39 | die "The callback parameter to map() must be a subroutine reference" | ||||
40 | unless ref( $callback ) eq 'CODE'; | ||||
41 | my $return = $class->empty_set; | ||||
42 | $return->{set} = $self->{set}->iterate( | ||||
43 | sub { | ||||
44 | local $_ = bless { set => $_[0]->clone }, 'DateTime::Span'; | ||||
45 | my @list = $callback->(); | ||||
46 | my $set = $class->empty_set; | ||||
47 | $set = $set->union( $_ ) for @list; | ||||
48 | return $set->{set}; | ||||
49 | } | ||||
50 | ); | ||||
51 | $return; | ||||
52 | } | ||||
53 | |||||
54 | sub grep { | ||||
55 | my ( $self, $callback ) = @_; | ||||
56 | my $class = ref( $self ); | ||||
57 | die "The callback parameter to grep() must be a subroutine reference" | ||||
58 | unless ref( $callback ) eq 'CODE'; | ||||
59 | my $return = $class->empty_set; | ||||
60 | $return->{set} = $self->{set}->iterate( | ||||
61 | sub { | ||||
62 | local $_ = bless { set => $_[0]->clone }, 'DateTime::Span'; | ||||
63 | my $result = $callback->(); | ||||
64 | return $_->{set} if $result && $_; | ||||
65 | return; | ||||
66 | } | ||||
67 | ); | ||||
68 | $return; | ||||
69 | } | ||||
70 | |||||
71 | sub set_time_zone { | ||||
72 | my ( $self, $tz ) = @_; | ||||
73 | |||||
74 | # TODO - use iterate() instead | ||||
75 | |||||
76 | my $result = $self->{set}->iterate( | ||||
77 | sub { | ||||
78 | my %tmp = %{ $_[0]->{list}[0] }; | ||||
79 | $tmp{a} = $tmp{a}->clone->set_time_zone( $tz ) if ref $tmp{a}; | ||||
80 | $tmp{b} = $tmp{b}->clone->set_time_zone( $tz ) if ref $tmp{b}; | ||||
81 | \%tmp; | ||||
82 | }, | ||||
83 | backtrack_callback => sub { | ||||
84 | my ( $min, $max ) = ( $_[0]->min, $_[0]->max ); | ||||
85 | if ( ref($min) ) | ||||
86 | { | ||||
87 | $min = $min->clone; | ||||
88 | $min->set_time_zone( 'floating' ); | ||||
89 | } | ||||
90 | if ( ref($max) ) | ||||
91 | { | ||||
92 | $max = $max->clone; | ||||
93 | $max->set_time_zone( 'floating' ); | ||||
94 | } | ||||
95 | return Set::Infinite::_recurrence->new( $min, $max ); | ||||
96 | }, | ||||
97 | ); | ||||
98 | |||||
99 | ### this code enables 'subroutine method' behaviour | ||||
100 | $self->{set} = $result; | ||||
101 | return $self; | ||||
102 | } | ||||
103 | |||||
104 | sub from_spans { | ||||
105 | my $class = shift; | ||||
106 | my %args = validate( @_, | ||||
107 | { spans => | ||||
108 | { type => ARRAYREF, | ||||
109 | optional => 1, | ||||
110 | }, | ||||
111 | } | ||||
112 | ); | ||||
113 | my $self = {}; | ||||
114 | my $set = Set::Infinite::_recurrence->new(); | ||||
115 | $set = $set->union( $_->{set} ) for @{ $args{spans} }; | ||||
116 | $self->{set} = $set; | ||||
117 | bless $self, $class; | ||||
118 | return $self; | ||||
119 | } | ||||
120 | |||||
121 | sub from_set_and_duration { | ||||
122 | # set => $dt_set, days => 1 | ||||
123 | my $class = shift; | ||||
124 | my %args = @_; | ||||
125 | my $set = delete $args{set} || | ||||
126 | carp "from_set_and_duration needs a 'set' parameter"; | ||||
127 | |||||
128 | $set = $set->as_set | ||||
129 | if UNIVERSAL::can( $set, 'as_set' ); | ||||
130 | unless ( UNIVERSAL::can( $set, 'union' ) ) { | ||||
131 | carp "'set' must be a set" }; | ||||
132 | |||||
133 | my $duration = delete $args{duration} || | ||||
134 | new DateTime::Duration( %args ); | ||||
135 | my $end_set = $set->clone->add_duration( $duration ); | ||||
136 | return $class->from_sets( start_set => $set, | ||||
137 | end_set => $end_set ); | ||||
138 | } | ||||
139 | |||||
140 | sub from_sets { | ||||
141 | my $class = shift; | ||||
142 | my %args = validate( @_, | ||||
143 | { start_set => | ||||
144 | { # can => 'union', | ||||
145 | optional => 0, | ||||
146 | }, | ||||
147 | end_set => | ||||
148 | { # can => 'union', | ||||
149 | optional => 0, | ||||
150 | }, | ||||
151 | } | ||||
152 | ); | ||||
153 | my $start_set = delete $args{start_set}; | ||||
154 | my $end_set = delete $args{end_set}; | ||||
155 | |||||
156 | $start_set = $start_set->as_set | ||||
157 | if UNIVERSAL::can( $start_set, 'as_set' ); | ||||
158 | $end_set = $end_set->as_set | ||||
159 | if UNIVERSAL::can( $end_set, 'as_set' ); | ||||
160 | |||||
161 | unless ( UNIVERSAL::can( $start_set, 'union' ) ) { | ||||
162 | carp "'start_set' must be a set" }; | ||||
163 | unless ( UNIVERSAL::can( $end_set, 'union' ) ) { | ||||
164 | carp "'end_set' must be a set" }; | ||||
165 | |||||
166 | my $self; | ||||
167 | $self->{set} = $start_set->{set}->until( | ||||
168 | $end_set->{set} ); | ||||
169 | bless $self, $class; | ||||
170 | return $self; | ||||
171 | } | ||||
172 | |||||
173 | sub start_set { | ||||
174 | if ( exists $_[0]->{set}{method} && | ||||
175 | $_[0]->{set}{method} eq 'until' ) | ||||
176 | { | ||||
177 | return bless { set => $_[0]->{set}{parent}[0] }, 'DateTime::Set'; | ||||
178 | } | ||||
179 | my $return = DateTime::Set->empty_set; | ||||
180 | $return->{set} = $_[0]->{set}->start_set; | ||||
181 | $return; | ||||
182 | } | ||||
183 | |||||
184 | sub end_set { | ||||
185 | if ( exists $_[0]->{set}{method} && | ||||
186 | $_[0]->{set}{method} eq 'until' ) | ||||
187 | { | ||||
188 | return bless { set => $_[0]->{set}{parent}[1] }, 'DateTime::Set'; | ||||
189 | } | ||||
190 | my $return = DateTime::Set->empty_set; | ||||
191 | $return->{set} = $_[0]->{set}->end_set; | ||||
192 | $return; | ||||
193 | } | ||||
194 | |||||
195 | sub empty_set { | ||||
196 | my $class = shift; | ||||
197 | |||||
198 | return bless { set => Set::Infinite::_recurrence->new }, $class; | ||||
199 | } | ||||
200 | |||||
201 | sub is_empty_set { | ||||
202 | my $set = $_[0]; | ||||
203 | $set->{set}->is_null; | ||||
204 | } | ||||
205 | |||||
206 | sub clone { | ||||
207 | bless { | ||||
208 | set => $_[0]->{set}->copy, | ||||
209 | }, ref $_[0]; | ||||
210 | } | ||||
211 | |||||
212 | |||||
213 | sub iterator { | ||||
214 | my $self = shift; | ||||
215 | |||||
216 | my %args = @_; | ||||
217 | my $span; | ||||
218 | $span = delete $args{span}; | ||||
219 | $span = DateTime::Span->new( %args ) if %args; | ||||
220 | |||||
221 | return $self->intersection( $span ) if $span; | ||||
222 | return $self->clone; | ||||
223 | } | ||||
224 | |||||
225 | |||||
226 | # next() gets the next element from an iterator() | ||||
227 | sub next { | ||||
228 | my ($self) = shift; | ||||
229 | |||||
230 | # TODO: this is fixing an error from elsewhere | ||||
231 | # - find out what's going on! (with "sunset.pl") | ||||
232 | return undef unless ref $self->{set}; | ||||
233 | |||||
234 | if ( @_ ) | ||||
235 | { | ||||
236 | my $max; | ||||
237 | $max = $_[0]->max if UNIVERSAL::can( $_[0], 'union' ); | ||||
238 | $max = $_[0] if ! defined $max; | ||||
239 | |||||
240 | return undef if ! ref( $max ) && $max == INFINITY; | ||||
241 | |||||
242 | my $span = DateTime::Span->from_datetimes( start => $max ); | ||||
243 | my $iterator = $self->intersection( $span ); | ||||
244 | my $return = $iterator->next; | ||||
245 | |||||
246 | return $return if ! defined $return; | ||||
247 | return $return if ! $return->intersects( $max ); | ||||
248 | |||||
249 | return $iterator->next; | ||||
250 | } | ||||
251 | |||||
252 | my ($head, $tail) = $self->{set}->first; | ||||
253 | $self->{set} = $tail; | ||||
254 | return $head unless ref $head; | ||||
255 | my $return = { | ||||
256 | set => $head, | ||||
257 | }; | ||||
258 | bless $return, 'DateTime::Span'; | ||||
259 | return $return; | ||||
260 | } | ||||
261 | |||||
262 | # previous() gets the last element from an iterator() | ||||
263 | sub previous { | ||||
264 | my ($self) = shift; | ||||
265 | |||||
266 | return undef unless ref $self->{set}; | ||||
267 | |||||
268 | if ( @_ ) | ||||
269 | { | ||||
270 | my $min; | ||||
271 | $min = $_[0]->min if UNIVERSAL::can( $_[0], 'union' ); | ||||
272 | $min = $_[0] if ! defined $min; | ||||
273 | |||||
274 | return undef if ! ref( $min ) && $min == INFINITY; | ||||
275 | |||||
276 | my $span = DateTime::Span->from_datetimes( end => $min ); | ||||
277 | my $iterator = $self->intersection( $span ); | ||||
278 | my $return = $iterator->previous; | ||||
279 | |||||
280 | return $return if ! defined $return; | ||||
281 | return $return if ! $return->intersects( $min ); | ||||
282 | |||||
283 | return $iterator->previous; | ||||
284 | } | ||||
285 | |||||
286 | my ($head, $tail) = $self->{set}->last; | ||||
287 | $self->{set} = $tail; | ||||
288 | return $head unless ref $head; | ||||
289 | my $return = { | ||||
290 | set => $head, | ||||
291 | }; | ||||
292 | bless $return, 'DateTime::Span'; | ||||
293 | return $return; | ||||
294 | } | ||||
295 | |||||
296 | # "current" means less-or-equal to a DateTime | ||||
297 | sub current { | ||||
298 | my $self = shift; | ||||
299 | |||||
300 | my $previous; | ||||
301 | my $next; | ||||
302 | { | ||||
303 | my $min; | ||||
304 | $min = $_[0]->min if UNIVERSAL::can( $_[0], 'union' ); | ||||
305 | $min = $_[0] if ! defined $min; | ||||
306 | return undef if ! ref( $min ) && $min == INFINITY; | ||||
307 | my $span = DateTime::Span->from_datetimes( end => $min ); | ||||
308 | my $iterator = $self->intersection( $span ); | ||||
309 | $previous = $iterator->previous; | ||||
310 | $span = DateTime::Span->from_datetimes( start => $min ); | ||||
311 | $iterator = $self->intersection( $span ); | ||||
312 | $next = $iterator->next; | ||||
313 | } | ||||
314 | return $previous unless defined $next; | ||||
315 | |||||
316 | my $dt1 = defined $previous | ||||
317 | ? $next->union( $previous ) | ||||
318 | : $next; | ||||
319 | |||||
320 | my $return = $dt1->intersected_spans( $_[0] ); | ||||
321 | |||||
322 | $return = $previous | ||||
323 | if !defined $return->max; | ||||
324 | |||||
325 | bless $return, 'DateTime::SpanSet' | ||||
326 | if defined $return; | ||||
327 | return $return; | ||||
328 | } | ||||
329 | |||||
330 | sub closest { | ||||
331 | my $self = shift; | ||||
332 | my $dt = shift; | ||||
333 | |||||
334 | my $dt1 = $self->current( $dt ); | ||||
335 | my $dt2 = $self->next( $dt ); | ||||
336 | bless $dt2, 'DateTime::SpanSet' | ||||
337 | if defined $dt2; | ||||
338 | |||||
339 | return $dt2 unless defined $dt1; | ||||
340 | return $dt1 unless defined $dt2; | ||||
341 | |||||
342 | $dt = DateTime::Set->from_datetimes( dates => [ $dt ] ) | ||||
343 | unless UNIVERSAL::can( $dt, 'union' ); | ||||
344 | |||||
345 | return $dt1 if $dt1->contains( $dt ); | ||||
346 | |||||
347 | my $delta = $dt->min - $dt1->max; | ||||
348 | return $dt1 if ( $dt2->min - $delta ) >= $dt->max; | ||||
349 | |||||
350 | return $dt2; | ||||
351 | } | ||||
352 | |||||
353 | sub as_list { | ||||
354 | my $self = shift; | ||||
355 | return undef unless ref( $self->{set} ); | ||||
356 | |||||
357 | my %args = @_; | ||||
358 | my $span; | ||||
359 | $span = delete $args{span}; | ||||
360 | $span = DateTime::Span->new( %args ) if %args; | ||||
361 | |||||
362 | my $set = $self->clone; | ||||
363 | $set = $set->intersection( $span ) if $span; | ||||
364 | |||||
365 | # Note: removing this line means we may end up in an infinite loop! | ||||
366 | return undef if $set->{set}->is_too_complex; # undef = no begin/end | ||||
367 | |||||
368 | # return if $set->{set}->is_null; # nothing = empty | ||||
369 | my @result; | ||||
370 | # we should extract _copies_ of the set elements, | ||||
371 | # such that the user can't modify the set indirectly | ||||
372 | |||||
373 | my $iter = $set->iterator; | ||||
374 | while ( my $dt = $iter->next ) | ||||
375 | { | ||||
376 | push @result, $dt | ||||
377 | if ref( $dt ); # we don't want to return INFINITY value | ||||
378 | }; | ||||
379 | |||||
380 | return @result; | ||||
381 | } | ||||
382 | |||||
383 | # Set::Infinite methods | ||||
384 | |||||
385 | sub intersection { | ||||
386 | my ($set1, $set2) = ( shift, shift ); | ||||
387 | my $class = ref($set1); | ||||
388 | my $tmp = $class->empty_set(); | ||||
389 | $set2 = $set2->as_spanset | ||||
390 | if $set2->can( 'as_spanset' ); | ||||
391 | $set2 = $set2->as_set | ||||
392 | if $set2->can( 'as_set' ); | ||||
393 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
394 | unless $set2->can( 'union' ); | ||||
395 | $tmp->{set} = $set1->{set}->intersection( $set2->{set} ); | ||||
396 | return $tmp; | ||||
397 | } | ||||
398 | |||||
399 | sub intersected_spans { | ||||
400 | my ($set1, $set2) = ( shift, shift ); | ||||
401 | my $class = ref($set1); | ||||
402 | my $tmp = $class->empty_set(); | ||||
403 | $set2 = $set2->as_spanset | ||||
404 | if $set2->can( 'as_spanset' ); | ||||
405 | $set2 = $set2->as_set | ||||
406 | if $set2->can( 'as_set' ); | ||||
407 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
408 | unless $set2->can( 'union' ); | ||||
409 | $tmp->{set} = $set1->{set}->intersected_spans( $set2->{set} ); | ||||
410 | return $tmp; | ||||
411 | } | ||||
412 | |||||
413 | sub intersects { | ||||
414 | my ($set1, $set2) = ( shift, shift ); | ||||
415 | |||||
416 | unless ( $set2->can( 'union' ) ) | ||||
417 | { | ||||
418 | for ( $set2, @_ ) | ||||
419 | { | ||||
420 | return 1 if $set1->contains( $_ ); | ||||
421 | } | ||||
422 | return 0; | ||||
423 | } | ||||
424 | |||||
425 | my $class = ref($set1); | ||||
426 | $set2 = $set2->as_spanset | ||||
427 | if $set2->can( 'as_spanset' ); | ||||
428 | $set2 = $set2->as_set | ||||
429 | if $set2->can( 'as_set' ); | ||||
430 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
431 | unless $set2->can( 'union' ); | ||||
432 | return $set1->{set}->intersects( $set2->{set} ); | ||||
433 | } | ||||
434 | |||||
435 | sub contains { | ||||
436 | my ($set1, $set2) = ( shift, shift ); | ||||
437 | |||||
438 | unless ( $set2->can( 'union' ) ) | ||||
439 | { | ||||
440 | if ( exists $set1->{set}{method} && | ||||
441 | $set1->{set}{method} eq 'until' ) | ||||
442 | { | ||||
443 | my $start_set = $set1->start_set; | ||||
444 | my $end_set = $set1->end_set; | ||||
445 | |||||
446 | for ( $set2, @_ ) | ||||
447 | { | ||||
448 | my $start = $start_set->next( $set2 ); | ||||
449 | my $end = $end_set->next( $set2 ); | ||||
450 | |||||
451 | goto ABORT unless defined $start && defined $end; | ||||
452 | |||||
453 | return 0 if $start < $end; | ||||
454 | } | ||||
455 | return 1; | ||||
456 | |||||
457 | ABORT: ; | ||||
458 | # don't know | ||||
459 | } | ||||
460 | } | ||||
461 | |||||
462 | my $class = ref($set1); | ||||
463 | $set2 = $set2->as_spanset | ||||
464 | if $set2->can( 'as_spanset' ); | ||||
465 | $set2 = $set2->as_set | ||||
466 | if $set2->can( 'as_set' ); | ||||
467 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
468 | unless $set2->can( 'union' ); | ||||
469 | return $set1->{set}->contains( $set2->{set} ); | ||||
470 | } | ||||
471 | |||||
472 | sub union { | ||||
473 | my ($set1, $set2) = ( shift, shift ); | ||||
474 | my $class = ref($set1); | ||||
475 | my $tmp = $class->empty_set(); | ||||
476 | $set2 = $set2->as_spanset | ||||
477 | if $set2->can( 'as_spanset' ); | ||||
478 | $set2 = $set2->as_set | ||||
479 | if $set2->can( 'as_set' ); | ||||
480 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
481 | unless $set2->can( 'union' ); | ||||
482 | $tmp->{set} = $set1->{set}->union( $set2->{set} ); | ||||
483 | return $tmp; | ||||
484 | } | ||||
485 | |||||
486 | sub complement { | ||||
487 | my ($set1, $set2) = ( shift, shift ); | ||||
488 | my $class = ref($set1); | ||||
489 | my $tmp = $class->empty_set(); | ||||
490 | if (defined $set2) { | ||||
491 | $set2 = $set2->as_spanset | ||||
492 | if $set2->can( 'as_spanset' ); | ||||
493 | $set2 = $set2->as_set | ||||
494 | if $set2->can( 'as_set' ); | ||||
495 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
496 | unless $set2->can( 'union' ); | ||||
497 | $tmp->{set} = $set1->{set}->complement( $set2->{set} ); | ||||
498 | } | ||||
499 | else { | ||||
500 | $tmp->{set} = $set1->{set}->complement; | ||||
501 | } | ||||
502 | return $tmp; | ||||
503 | } | ||||
504 | |||||
505 | sub min { | ||||
506 | return DateTime::Set::_fix_datetime( $_[0]->{set}->min ); | ||||
507 | } | ||||
508 | |||||
509 | sub max { | ||||
510 | return DateTime::Set::_fix_datetime( $_[0]->{set}->max ); | ||||
511 | } | ||||
512 | |||||
513 | # returns a DateTime::Span | ||||
514 | sub span { | ||||
515 | my $set = $_[0]->{set}->span; | ||||
516 | my $self = bless { set => $set }, 'DateTime::Span'; | ||||
517 | return $self; | ||||
518 | } | ||||
519 | |||||
520 | # returns a DateTime::Duration | ||||
521 | sub duration { | ||||
522 | my $dur; | ||||
523 | |||||
524 | return DateTime::Duration->new( seconds => 0 ) | ||||
525 | if $_[0]->{set}->is_empty; | ||||
526 | |||||
527 | local $@; | ||||
528 | eval { | ||||
529 | local $SIG{__DIE__}; # don't want to trap this (rt ticket 5434) | ||||
530 | $dur = $_[0]->{set}->size | ||||
531 | }; | ||||
532 | |||||
533 | return $dur if defined $dur && ref( $dur ); | ||||
534 | return DateTime::Infinite::Future->new - | ||||
535 | DateTime::Infinite::Past->new; | ||||
536 | # return INFINITY; | ||||
537 | } | ||||
538 | 1 | 1µs | *size = \&duration; | ||
539 | |||||
540 | 1 | 3µs | 1; | ||
541 | |||||
542 | __END__ |