Filename | /usr/share/perl5/DateTime/SpanSet.pm |
Statements | Executed 27 statements in 3.81ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 38µs | 38µs | BEGIN@10 | DateTime::SpanSet::
1 | 1 | 1 | 28µs | 34µs | BEGIN@7 | DateTime::SpanSet::
1 | 1 | 1 | 16µs | 87µs | BEGIN@13 | DateTime::SpanSet::
1 | 1 | 1 | 15µs | 77µs | BEGIN@12 | DateTime::SpanSet::
1 | 1 | 1 | 15µs | 69µs | BEGIN@16 | DateTime::SpanSet::
1 | 1 | 1 | 13µs | 89µs | BEGIN@17 | DateTime::SpanSet::
1 | 1 | 1 | 10µs | 33µs | BEGIN@14 | DateTime::SpanSet::
1 | 1 | 1 | 9µs | 9µ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 | 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 | 3 | 51µs | 2 | 40µs | # spent 34µs (28+6) within DateTime::SpanSet::BEGIN@7 which was called:
# once (28µs+6µs) by DateTime::Span::BEGIN@10 at line 7 # spent 34µs making 1 call to DateTime::SpanSet::BEGIN@7
# spent 6µs making 1 call to strict::import |
8 | |||||
9 | 3 | 48µs | 1 | 9µs | # spent 9µs within DateTime::SpanSet::BEGIN@9 which was called:
# once (9µs+0s) by DateTime::Span::BEGIN@10 at line 9 # spent 9µs making 1 call to DateTime::SpanSet::BEGIN@9 |
10 | 3 | 64µs | 1 | 38µs | # spent 38µs within DateTime::SpanSet::BEGIN@10 which was called:
# once (38µs+0s) by DateTime::Span::BEGIN@10 at line 10 # spent 38µs making 1 call to DateTime::SpanSet::BEGIN@10 |
11 | |||||
12 | 3 | 53µs | 2 | 139µs | # spent 77µs (15+62) within DateTime::SpanSet::BEGIN@12 which was called:
# once (15µs+62µs) by DateTime::Span::BEGIN@10 at line 12 # spent 77µs making 1 call to DateTime::SpanSet::BEGIN@12
# spent 62µs making 1 call to Exporter::import |
13 | 3 | 38µs | 2 | 157µs | # spent 87µs (16+71) within DateTime::SpanSet::BEGIN@13 which was called:
# once (16µs+71µs) by DateTime::Span::BEGIN@10 at line 13 # spent 87µs making 1 call to DateTime::SpanSet::BEGIN@13
# spent 71µs making 1 call to Exporter::import |
14 | 3 | 50µs | 2 | 56µs | # spent 33µs (10+23) within DateTime::SpanSet::BEGIN@14 which was called:
# once (10µs+23µs) by DateTime::Span::BEGIN@10 at line 14 # spent 33µs making 1 call to DateTime::SpanSet::BEGIN@14
# spent 23µs making 1 call to vars::import |
15 | |||||
16 | 3 | 45µs | 2 | 124µs | # spent 69µs (15+54) within DateTime::SpanSet::BEGIN@16 which was called:
# once (15µs+54µs) by DateTime::Span::BEGIN@10 at line 16 # spent 69µs making 1 call to DateTime::SpanSet::BEGIN@16
# spent 54µs making 1 call to constant::import |
17 | 3 | 3.45ms | 2 | 165µs | # spent 89µs (13+76) within DateTime::SpanSet::BEGIN@17 which was called:
# once (13µs+76µs) by DateTime::Span::BEGIN@10 at line 17 # spent 89µs making 1 call to DateTime::SpanSet::BEGIN@17
# spent 76µs making 1 call to constant::import |
18 | 1 | 400ns | $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 $_ 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 clone { | ||||
202 | bless { | ||||
203 | set => $_[0]->{set}->copy, | ||||
204 | }, ref $_[0]; | ||||
205 | } | ||||
206 | |||||
207 | |||||
208 | sub iterator { | ||||
209 | my $self = shift; | ||||
210 | |||||
211 | my %args = @_; | ||||
212 | my $span; | ||||
213 | $span = delete $args{span}; | ||||
214 | $span = DateTime::Span->new( %args ) if %args; | ||||
215 | |||||
216 | return $self->intersection( $span ) if $span; | ||||
217 | return $self->clone; | ||||
218 | } | ||||
219 | |||||
220 | |||||
221 | # next() gets the next element from an iterator() | ||||
222 | sub next { | ||||
223 | my ($self) = shift; | ||||
224 | |||||
225 | # TODO: this is fixing an error from elsewhere | ||||
226 | # - find out what's going on! (with "sunset.pl") | ||||
227 | return undef unless ref $self->{set}; | ||||
228 | |||||
229 | if ( @_ ) | ||||
230 | { | ||||
231 | my $max; | ||||
232 | $max = $_[0]->max if UNIVERSAL::can( $_[0], 'union' ); | ||||
233 | $max = $_[0] if ! defined $max; | ||||
234 | |||||
235 | return undef if ! ref( $max ) && $max == INFINITY; | ||||
236 | |||||
237 | my $span = DateTime::Span->from_datetimes( start => $max ); | ||||
238 | my $iterator = $self->intersection( $span ); | ||||
239 | my $return = $iterator->next; | ||||
240 | |||||
241 | return $return if ! defined $return; | ||||
242 | return $return if ! $return->intersects( $max ); | ||||
243 | |||||
244 | return $iterator->next; | ||||
245 | } | ||||
246 | |||||
247 | my ($head, $tail) = $self->{set}->first; | ||||
248 | $self->{set} = $tail; | ||||
249 | return $head unless ref $head; | ||||
250 | my $return = { | ||||
251 | set => $head, | ||||
252 | }; | ||||
253 | bless $return, 'DateTime::Span'; | ||||
254 | return $return; | ||||
255 | } | ||||
256 | |||||
257 | # previous() gets the last element from an iterator() | ||||
258 | sub previous { | ||||
259 | my ($self) = shift; | ||||
260 | |||||
261 | return undef unless ref $self->{set}; | ||||
262 | |||||
263 | if ( @_ ) | ||||
264 | { | ||||
265 | my $min; | ||||
266 | $min = $_[0]->min if UNIVERSAL::can( $_[0], 'union' ); | ||||
267 | $min = $_[0] if ! defined $min; | ||||
268 | |||||
269 | return undef if ! ref( $min ) && $min == INFINITY; | ||||
270 | |||||
271 | my $span = DateTime::Span->from_datetimes( end => $min ); | ||||
272 | my $iterator = $self->intersection( $span ); | ||||
273 | my $return = $iterator->previous; | ||||
274 | |||||
275 | return $return if ! defined $return; | ||||
276 | return $return if ! $return->intersects( $min ); | ||||
277 | |||||
278 | return $iterator->previous; | ||||
279 | } | ||||
280 | |||||
281 | my ($head, $tail) = $self->{set}->last; | ||||
282 | $self->{set} = $tail; | ||||
283 | return $head unless ref $head; | ||||
284 | my $return = { | ||||
285 | set => $head, | ||||
286 | }; | ||||
287 | bless $return, 'DateTime::Span'; | ||||
288 | return $return; | ||||
289 | } | ||||
290 | |||||
291 | # "current" means less-or-equal to a DateTime | ||||
292 | sub current { | ||||
293 | my $self = shift; | ||||
294 | |||||
295 | my $previous; | ||||
296 | my $next; | ||||
297 | { | ||||
298 | my $min; | ||||
299 | $min = $_[0]->min if UNIVERSAL::can( $_[0], 'union' ); | ||||
300 | $min = $_[0] if ! defined $min; | ||||
301 | return undef if ! ref( $min ) && $min == INFINITY; | ||||
302 | my $span = DateTime::Span->from_datetimes( end => $min ); | ||||
303 | my $iterator = $self->intersection( $span ); | ||||
304 | $previous = $iterator->previous; | ||||
305 | $span = DateTime::Span->from_datetimes( start => $min ); | ||||
306 | $iterator = $self->intersection( $span ); | ||||
307 | $next = $iterator->next; | ||||
308 | } | ||||
309 | return $previous unless defined $next; | ||||
310 | |||||
311 | my $dt1 = defined $previous | ||||
312 | ? $next->union( $previous ) | ||||
313 | : $next; | ||||
314 | |||||
315 | my $return = $dt1->intersected_spans( $_[0] ); | ||||
316 | |||||
317 | $return = $previous | ||||
318 | if !defined $return->max; | ||||
319 | |||||
320 | bless $return, 'DateTime::SpanSet' | ||||
321 | if defined $return; | ||||
322 | return $return; | ||||
323 | } | ||||
324 | |||||
325 | sub closest { | ||||
326 | my $self = shift; | ||||
327 | my $dt = shift; | ||||
328 | |||||
329 | my $dt1 = $self->current( $dt ); | ||||
330 | my $dt2 = $self->next( $dt ); | ||||
331 | bless $dt2, 'DateTime::SpanSet' | ||||
332 | if defined $dt2; | ||||
333 | |||||
334 | return $dt2 unless defined $dt1; | ||||
335 | return $dt1 unless defined $dt2; | ||||
336 | |||||
337 | $dt = DateTime::Set->from_datetimes( dates => [ $dt ] ) | ||||
338 | unless UNIVERSAL::can( $dt, 'union' ); | ||||
339 | |||||
340 | return $dt1 if $dt1->contains( $dt ); | ||||
341 | |||||
342 | my $delta = $dt->min - $dt1->max; | ||||
343 | return $dt1 if ( $dt2->min - $delta ) >= $dt->max; | ||||
344 | |||||
345 | return $dt2; | ||||
346 | } | ||||
347 | |||||
348 | sub as_list { | ||||
349 | my $self = shift; | ||||
350 | return undef unless ref( $self->{set} ); | ||||
351 | |||||
352 | my %args = @_; | ||||
353 | my $span; | ||||
354 | $span = delete $args{span}; | ||||
355 | $span = DateTime::Span->new( %args ) if %args; | ||||
356 | |||||
357 | my $set = $self->clone; | ||||
358 | $set = $set->intersection( $span ) if $span; | ||||
359 | |||||
360 | # Note: removing this line means we may end up in an infinite loop! | ||||
361 | return undef if $set->{set}->is_too_complex; # undef = no begin/end | ||||
362 | |||||
363 | # return if $set->{set}->is_null; # nothing = empty | ||||
364 | my @result; | ||||
365 | # we should extract _copies_ of the set elements, | ||||
366 | # such that the user can't modify the set indirectly | ||||
367 | |||||
368 | my $iter = $set->iterator; | ||||
369 | while ( my $dt = $iter->next ) | ||||
370 | { | ||||
371 | push @result, $dt | ||||
372 | if ref( $dt ); # we don't want to return INFINITY value | ||||
373 | }; | ||||
374 | |||||
375 | return @result; | ||||
376 | } | ||||
377 | |||||
378 | # Set::Infinite methods | ||||
379 | |||||
380 | sub intersection { | ||||
381 | my ($set1, $set2) = ( shift, shift ); | ||||
382 | my $class = ref($set1); | ||||
383 | my $tmp = $class->empty_set(); | ||||
384 | $set2 = $set2->as_spanset | ||||
385 | if $set2->can( 'as_spanset' ); | ||||
386 | $set2 = $set2->as_set | ||||
387 | if $set2->can( 'as_set' ); | ||||
388 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
389 | unless $set2->can( 'union' ); | ||||
390 | $tmp->{set} = $set1->{set}->intersection( $set2->{set} ); | ||||
391 | return $tmp; | ||||
392 | } | ||||
393 | |||||
394 | sub intersected_spans { | ||||
395 | my ($set1, $set2) = ( shift, shift ); | ||||
396 | my $class = ref($set1); | ||||
397 | my $tmp = $class->empty_set(); | ||||
398 | $set2 = $set2->as_spanset | ||||
399 | if $set2->can( 'as_spanset' ); | ||||
400 | $set2 = $set2->as_set | ||||
401 | if $set2->can( 'as_set' ); | ||||
402 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
403 | unless $set2->can( 'union' ); | ||||
404 | $tmp->{set} = $set1->{set}->intersected_spans( $set2->{set} ); | ||||
405 | return $tmp; | ||||
406 | } | ||||
407 | |||||
408 | sub intersects { | ||||
409 | my ($set1, $set2) = ( shift, shift ); | ||||
410 | |||||
411 | unless ( $set2->can( 'union' ) ) | ||||
412 | { | ||||
413 | for ( $set2, @_ ) | ||||
414 | { | ||||
415 | return 1 if $set1->contains( $_ ); | ||||
416 | } | ||||
417 | return 0; | ||||
418 | } | ||||
419 | |||||
420 | my $class = ref($set1); | ||||
421 | $set2 = $set2->as_spanset | ||||
422 | if $set2->can( 'as_spanset' ); | ||||
423 | $set2 = $set2->as_set | ||||
424 | if $set2->can( 'as_set' ); | ||||
425 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
426 | unless $set2->can( 'union' ); | ||||
427 | return $set1->{set}->intersects( $set2->{set} ); | ||||
428 | } | ||||
429 | |||||
430 | sub contains { | ||||
431 | my ($set1, $set2) = ( shift, shift ); | ||||
432 | |||||
433 | unless ( $set2->can( 'union' ) ) | ||||
434 | { | ||||
435 | if ( exists $set1->{set}{method} && | ||||
436 | $set1->{set}{method} eq 'until' ) | ||||
437 | { | ||||
438 | my $start_set = $set1->start_set; | ||||
439 | my $end_set = $set1->end_set; | ||||
440 | |||||
441 | for ( $set2, @_ ) | ||||
442 | { | ||||
443 | my $start = $start_set->next( $set2 ); | ||||
444 | my $end = $end_set->next( $set2 ); | ||||
445 | |||||
446 | goto ABORT unless defined $start && defined $end; | ||||
447 | |||||
448 | return 0 if $start < $end; | ||||
449 | } | ||||
450 | return 1; | ||||
451 | |||||
452 | ABORT: ; | ||||
453 | # don't know | ||||
454 | } | ||||
455 | } | ||||
456 | |||||
457 | my $class = ref($set1); | ||||
458 | $set2 = $set2->as_spanset | ||||
459 | if $set2->can( 'as_spanset' ); | ||||
460 | $set2 = $set2->as_set | ||||
461 | if $set2->can( 'as_set' ); | ||||
462 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
463 | unless $set2->can( 'union' ); | ||||
464 | return $set1->{set}->contains( $set2->{set} ); | ||||
465 | } | ||||
466 | |||||
467 | sub union { | ||||
468 | my ($set1, $set2) = ( shift, shift ); | ||||
469 | my $class = ref($set1); | ||||
470 | my $tmp = $class->empty_set(); | ||||
471 | $set2 = $set2->as_spanset | ||||
472 | if $set2->can( 'as_spanset' ); | ||||
473 | $set2 = $set2->as_set | ||||
474 | if $set2->can( 'as_set' ); | ||||
475 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
476 | unless $set2->can( 'union' ); | ||||
477 | $tmp->{set} = $set1->{set}->union( $set2->{set} ); | ||||
478 | return $tmp; | ||||
479 | } | ||||
480 | |||||
481 | sub complement { | ||||
482 | my ($set1, $set2) = ( shift, shift ); | ||||
483 | my $class = ref($set1); | ||||
484 | my $tmp = $class->empty_set(); | ||||
485 | if (defined $set2) { | ||||
486 | $set2 = $set2->as_spanset | ||||
487 | if $set2->can( 'as_spanset' ); | ||||
488 | $set2 = $set2->as_set | ||||
489 | if $set2->can( 'as_set' ); | ||||
490 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2, @_ ] ) | ||||
491 | unless $set2->can( 'union' ); | ||||
492 | $tmp->{set} = $set1->{set}->complement( $set2->{set} ); | ||||
493 | } | ||||
494 | else { | ||||
495 | $tmp->{set} = $set1->{set}->complement; | ||||
496 | } | ||||
497 | return $tmp; | ||||
498 | } | ||||
499 | |||||
500 | sub min { | ||||
501 | return DateTime::Set::_fix_datetime( $_[0]->{set}->min ); | ||||
502 | } | ||||
503 | |||||
504 | sub max { | ||||
505 | return DateTime::Set::_fix_datetime( $_[0]->{set}->max ); | ||||
506 | } | ||||
507 | |||||
508 | # returns a DateTime::Span | ||||
509 | sub span { | ||||
510 | my $set = $_[0]->{set}->span; | ||||
511 | my $self = bless { set => $set }, 'DateTime::Span'; | ||||
512 | return $self; | ||||
513 | } | ||||
514 | |||||
515 | # returns a DateTime::Duration | ||||
516 | sub duration { | ||||
517 | my $dur; | ||||
518 | |||||
519 | return DateTime::Duration->new( seconds => 0 ) | ||||
520 | if $_[0]->{set}->is_empty; | ||||
521 | |||||
522 | local $@; | ||||
523 | eval { | ||||
524 | local $SIG{__DIE__}; # don't want to trap this (rt ticket 5434) | ||||
525 | $dur = $_[0]->{set}->size | ||||
526 | }; | ||||
527 | |||||
528 | return $dur if defined $dur && ref( $dur ); | ||||
529 | return DateTime::Infinite::Future->new - | ||||
530 | DateTime::Infinite::Past->new; | ||||
531 | # return INFINITY; | ||||
532 | } | ||||
533 | 1 | 2µs | *size = \&duration; | ||
534 | |||||
535 | 1 | 5µs | 1; | ||
536 | |||||
537 | __END__ |