Filename | /usr/share/perl5/DateTime/Span.pm |
Statements | Executed 26 statements in 1.95ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 3.85ms | 4.29ms | BEGIN@10 | DateTime::Span::
1 | 1 | 1 | 21µs | 96µs | BEGIN@12 | DateTime::Span::
1 | 1 | 1 | 17µs | 22µs | BEGIN@7 | DateTime::Span::
1 | 1 | 1 | 14µs | 44µs | BEGIN@13 | DateTime::Span::
1 | 1 | 1 | 10µs | 48µs | BEGIN@15 | DateTime::Span::
1 | 1 | 1 | 9µs | 9µs | BEGIN@9 | DateTime::Span::
1 | 1 | 1 | 8µs | 39µs | BEGIN@16 | DateTime::Span::
0 | 0 | 0 | 0s | 0s | __ANON__[:28] | DateTime::Span::
0 | 0 | 0 | 0s | 0s | clone | DateTime::Span::
0 | 0 | 0 | 0s | 0s | complement | DateTime::Span::
0 | 0 | 0 | 0s | 0s | contains | DateTime::Span::
0 | 0 | 0 | 0s | 0s | duration | DateTime::Span::
0 | 0 | 0 | 0s | 0s | end | DateTime::Span::
0 | 0 | 0 | 0s | 0s | end_is_closed | DateTime::Span::
0 | 0 | 0 | 0s | 0s | end_is_open | DateTime::Span::
0 | 0 | 0 | 0s | 0s | from_datetime_and_duration | DateTime::Span::
0 | 0 | 0 | 0s | 0s | from_datetimes | DateTime::Span::
0 | 0 | 0 | 0s | 0s | intersection | DateTime::Span::
0 | 0 | 0 | 0s | 0s | intersects | DateTime::Span::
0 | 0 | 0 | 0s | 0s | new | DateTime::Span::
0 | 0 | 0 | 0s | 0s | set_time_zone | DateTime::Span::
0 | 0 | 0 | 0s | 0s | span | DateTime::Span::
0 | 0 | 0 | 0s | 0s | start | DateTime::Span::
0 | 0 | 0 | 0s | 0s | start_is_closed | DateTime::Span::
0 | 0 | 0 | 0s | 0s | start_is_open | DateTime::Span::
0 | 0 | 0 | 0s | 0s | union | DateTime::Span::
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::Span; | ||||
6 | |||||
7 | 3 | 27µs | 2 | 26µs | # spent 22µs (17+4) within DateTime::Span::BEGIN@7 which was called:
# once (17µs+4µs) by DateTime::Set::BEGIN@9 at line 7 # spent 22µs making 1 call to DateTime::Span::BEGIN@7
# spent 4µs making 1 call to strict::import |
8 | |||||
9 | 3 | 46µs | 1 | 9µs | # spent 9µs within DateTime::Span::BEGIN@9 which was called:
# once (9µs+0s) by DateTime::Set::BEGIN@9 at line 9 # spent 9µs making 1 call to DateTime::Span::BEGIN@9 |
10 | 3 | 200µs | 1 | 4.29ms | # spent 4.29ms (3.85+435µs) within DateTime::Span::BEGIN@10 which was called:
# once (3.85ms+435µs) by DateTime::Set::BEGIN@9 at line 10 # spent 4.29ms making 1 call to DateTime::Span::BEGIN@10 |
11 | |||||
12 | 3 | 57µs | 2 | 172µs | # spent 96µs (21+76) within DateTime::Span::BEGIN@12 which was called:
# once (21µs+76µs) by DateTime::Set::BEGIN@9 at line 12 # spent 96µs making 1 call to DateTime::Span::BEGIN@12
# spent 76µs making 1 call to Exporter::import |
13 | 3 | 38µs | 2 | 75µs | # spent 44µs (14+31) within DateTime::Span::BEGIN@13 which was called:
# once (14µs+31µs) by DateTime::Set::BEGIN@9 at line 13 # spent 44µs making 1 call to DateTime::Span::BEGIN@13
# spent 31µs making 1 call to vars::import |
14 | |||||
15 | 3 | 34µs | 2 | 86µs | # spent 48µs (10+38) within DateTime::Span::BEGIN@15 which was called:
# once (10µs+38µs) by DateTime::Set::BEGIN@9 at line 15 # spent 48µs making 1 call to DateTime::Span::BEGIN@15
# spent 38µs making 1 call to constant::import |
16 | 3 | 1.54ms | 2 | 70µs | # spent 39µs (8+31) within DateTime::Span::BEGIN@16 which was called:
# once (8µs+31µs) by DateTime::Set::BEGIN@9 at line 16 # spent 39µs making 1 call to DateTime::Span::BEGIN@16
# spent 31µs making 1 call to constant::import |
17 | 1 | 500ns | $VERSION = $DateTime::Set::VERSION; | ||
18 | |||||
19 | sub set_time_zone { | ||||
20 | my ( $self, $tz ) = @_; | ||||
21 | |||||
22 | $self->{set} = $self->{set}->iterate( | ||||
23 | sub { | ||||
24 | my %tmp = %{ $_[0]->{list}[0] }; | ||||
25 | $tmp{a} = $tmp{a}->clone->set_time_zone( $tz ) if ref $tmp{a}; | ||||
26 | $tmp{b} = $tmp{b}->clone->set_time_zone( $tz ) if ref $tmp{b}; | ||||
27 | \%tmp; | ||||
28 | } | ||||
29 | ); | ||||
30 | return $self; | ||||
31 | } | ||||
32 | |||||
33 | # note: the constructor must clone its DateTime parameters, such that | ||||
34 | # the set elements become immutable | ||||
35 | sub from_datetimes { | ||||
36 | my $class = shift; | ||||
37 | my %args = validate( @_, | ||||
38 | { start => | ||||
39 | { type => OBJECT, | ||||
40 | optional => 1, | ||||
41 | }, | ||||
42 | end => | ||||
43 | { type => OBJECT, | ||||
44 | optional => 1, | ||||
45 | }, | ||||
46 | after => | ||||
47 | { type => OBJECT, | ||||
48 | optional => 1, | ||||
49 | }, | ||||
50 | before => | ||||
51 | { type => OBJECT, | ||||
52 | optional => 1, | ||||
53 | }, | ||||
54 | } | ||||
55 | ); | ||||
56 | my $self = {}; | ||||
57 | my $set; | ||||
58 | |||||
59 | die "No arguments given to DateTime::Span->from_datetimes\n" | ||||
60 | unless keys %args; | ||||
61 | |||||
62 | if ( exists $args{start} && exists $args{after} ) { | ||||
63 | die "Cannot give both start and after arguments to DateTime::Span->from_datetimes\n"; | ||||
64 | } | ||||
65 | if ( exists $args{end} && exists $args{before} ) { | ||||
66 | die "Cannot give both end and before arguments to DateTime::Span->from_datetimes\n"; | ||||
67 | } | ||||
68 | |||||
69 | my ( $start, $open_start, $end, $open_end ); | ||||
70 | ( $start, $open_start ) = ( NEG_INFINITY, 0 ); | ||||
71 | ( $start, $open_start ) = ( $args{start}, 0 ) if exists $args{start}; | ||||
72 | ( $start, $open_start ) = ( $args{after}, 1 ) if exists $args{after}; | ||||
73 | ( $end, $open_end ) = ( INFINITY, 0 ); | ||||
74 | ( $end, $open_end ) = ( $args{end}, 0 ) if exists $args{end}; | ||||
75 | ( $end, $open_end ) = ( $args{before}, 1 ) if exists $args{before}; | ||||
76 | |||||
77 | if ( $start > $end ) { | ||||
78 | die "Span cannot start after the end in DateTime::Span->from_datetimes\n"; | ||||
79 | } | ||||
80 | $set = Set::Infinite::_recurrence->new( $start, $end ); | ||||
81 | if ( $start != $end ) { | ||||
82 | # remove start, such that we have ">" instead of ">=" | ||||
83 | $set = $set->complement( $start ) if $open_start; | ||||
84 | # remove end, such that we have "<" instead of "<=" | ||||
85 | $set = $set->complement( $end ) if $open_end; | ||||
86 | } | ||||
87 | |||||
88 | $self->{set} = $set; | ||||
89 | bless $self, $class; | ||||
90 | return $self; | ||||
91 | } | ||||
92 | |||||
93 | sub from_datetime_and_duration { | ||||
94 | my $class = shift; | ||||
95 | my %args = @_; | ||||
96 | |||||
97 | my $key; | ||||
98 | my $dt; | ||||
99 | # extract datetime parameters | ||||
100 | for ( qw( start end before after ) ) { | ||||
101 | if ( exists $args{$_} ) { | ||||
102 | $key = $_; | ||||
103 | $dt = delete $args{$_}; | ||||
104 | } | ||||
105 | } | ||||
106 | |||||
107 | # extract duration parameters | ||||
108 | my $dt_duration; | ||||
109 | if ( exists $args{duration} ) { | ||||
110 | $dt_duration = $args{duration}; | ||||
111 | } | ||||
112 | else { | ||||
113 | $dt_duration = DateTime::Duration->new( %args ); | ||||
114 | } | ||||
115 | # warn "Creating span from $key => ".$dt->datetime." and $dt_duration"; | ||||
116 | my $other_date = $dt->clone->add_duration( $dt_duration ); | ||||
117 | # warn "Creating span from $key => ".$dt->datetime." and ".$other_date->datetime; | ||||
118 | my $other_key; | ||||
119 | if ( $dt_duration->is_positive ) { | ||||
120 | # check if have to invert keys | ||||
121 | $key = 'after' if $key eq 'end'; | ||||
122 | $key = 'start' if $key eq 'before'; | ||||
123 | $other_key = 'before'; | ||||
124 | } | ||||
125 | else { | ||||
126 | # check if have to invert keys | ||||
127 | $other_key = 'end' if $key eq 'after'; | ||||
128 | $other_key = 'before' if $key eq 'start'; | ||||
129 | $key = 'start'; | ||||
130 | } | ||||
131 | return $class->new( $key => $dt, $other_key => $other_date ); | ||||
132 | } | ||||
133 | |||||
134 | # This method is intentionally not documented. It's really only for | ||||
135 | # use by ::Set and ::SpanSet's as_list() and iterator() methods. | ||||
136 | sub new { | ||||
137 | my $class = shift; | ||||
138 | my %args = @_; | ||||
139 | |||||
140 | # If we find anything _not_ appropriate for from_datetimes, we | ||||
141 | # assume it must be for durations, and call this constructor. | ||||
142 | # This way, we don't need to hardcode the DateTime::Duration | ||||
143 | # parameters. | ||||
144 | foreach ( keys %args ) | ||||
145 | { | ||||
146 | return $class->from_datetime_and_duration(%args) | ||||
147 | unless /^(?:before|after|start|end)$/; | ||||
148 | } | ||||
149 | |||||
150 | return $class->from_datetimes(%args); | ||||
151 | } | ||||
152 | |||||
153 | sub clone { | ||||
154 | bless { | ||||
155 | set => $_[0]->{set}->copy, | ||||
156 | }, ref $_[0]; | ||||
157 | } | ||||
158 | |||||
159 | # Set::Infinite methods | ||||
160 | |||||
161 | sub intersection { | ||||
162 | my ($set1, $set2) = @_; | ||||
163 | my $class = ref($set1); | ||||
164 | my $tmp = {}; # $class->new(); | ||||
165 | $set2 = $set2->as_spanset | ||||
166 | if $set2->can( 'as_spanset' ); | ||||
167 | $set2 = $set2->as_set | ||||
168 | if $set2->can( 'as_set' ); | ||||
169 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2 ] ) | ||||
170 | unless $set2->can( 'union' ); | ||||
171 | $tmp->{set} = $set1->{set}->intersection( $set2->{set} ); | ||||
172 | |||||
173 | # intersection() can generate something more complex than a span. | ||||
174 | bless $tmp, 'DateTime::SpanSet'; | ||||
175 | |||||
176 | return $tmp; | ||||
177 | } | ||||
178 | |||||
179 | sub intersects { | ||||
180 | my ($set1, $set2) = @_; | ||||
181 | my $class = ref($set1); | ||||
182 | $set2 = $set2->as_spanset | ||||
183 | if $set2->can( 'as_spanset' ); | ||||
184 | $set2 = $set2->as_set | ||||
185 | if $set2->can( 'as_set' ); | ||||
186 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2 ] ) | ||||
187 | unless $set2->can( 'union' ); | ||||
188 | return $set1->{set}->intersects( $set2->{set} ); | ||||
189 | } | ||||
190 | |||||
191 | sub contains { | ||||
192 | my ($set1, $set2) = @_; | ||||
193 | my $class = ref($set1); | ||||
194 | $set2 = $set2->as_spanset | ||||
195 | if $set2->can( 'as_spanset' ); | ||||
196 | $set2 = $set2->as_set | ||||
197 | if $set2->can( 'as_set' ); | ||||
198 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2 ] ) | ||||
199 | unless $set2->can( 'union' ); | ||||
200 | return $set1->{set}->contains( $set2->{set} ); | ||||
201 | } | ||||
202 | |||||
203 | sub union { | ||||
204 | my ($set1, $set2) = @_; | ||||
205 | my $class = ref($set1); | ||||
206 | my $tmp = {}; # $class->new(); | ||||
207 | $set2 = $set2->as_spanset | ||||
208 | if $set2->can( 'as_spanset' ); | ||||
209 | $set2 = $set2->as_set | ||||
210 | if $set2->can( 'as_set' ); | ||||
211 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2 ] ) | ||||
212 | unless $set2->can( 'union' ); | ||||
213 | $tmp->{set} = $set1->{set}->union( $set2->{set} ); | ||||
214 | |||||
215 | # union() can generate something more complex than a span. | ||||
216 | bless $tmp, 'DateTime::SpanSet'; | ||||
217 | |||||
218 | # # We have to check it's internal structure to find out. | ||||
219 | # if ( $#{ $tmp->{set}->{list} } != 0 ) { | ||||
220 | # bless $tmp, 'Date::SpanSet'; | ||||
221 | # } | ||||
222 | |||||
223 | return $tmp; | ||||
224 | } | ||||
225 | |||||
226 | sub complement { | ||||
227 | my ($set1, $set2) = @_; | ||||
228 | my $class = ref($set1); | ||||
229 | my $tmp = {}; # $class->new; | ||||
230 | if (defined $set2) { | ||||
231 | $set2 = $set2->as_spanset | ||||
232 | if $set2->can( 'as_spanset' ); | ||||
233 | $set2 = $set2->as_set | ||||
234 | if $set2->can( 'as_set' ); | ||||
235 | $set2 = DateTime::Set->from_datetimes( dates => [ $set2 ] ) | ||||
236 | unless $set2->can( 'union' ); | ||||
237 | $tmp->{set} = $set1->{set}->complement( $set2->{set} ); | ||||
238 | } | ||||
239 | else { | ||||
240 | $tmp->{set} = $set1->{set}->complement; | ||||
241 | } | ||||
242 | |||||
243 | # complement() can generate something more complex than a span. | ||||
244 | bless $tmp, 'DateTime::SpanSet'; | ||||
245 | |||||
246 | # # We have to check it's internal structure to find out. | ||||
247 | # if ( $#{ $tmp->{set}->{list} } != 0 ) { | ||||
248 | # bless $tmp, 'Date::SpanSet'; | ||||
249 | # } | ||||
250 | |||||
251 | return $tmp; | ||||
252 | } | ||||
253 | |||||
254 | sub start { | ||||
255 | return DateTime::Set::_fix_datetime( $_[0]->{set}->min ); | ||||
256 | } | ||||
257 | |||||
258 | 1 | 2µs | *min = \&start; | ||
259 | |||||
260 | sub end { | ||||
261 | return DateTime::Set::_fix_datetime( $_[0]->{set}->max ); | ||||
262 | } | ||||
263 | |||||
264 | 1 | 600ns | *max = \&end; | ||
265 | |||||
266 | sub start_is_open { | ||||
267 | # min_a returns info about the set boundary | ||||
268 | my ($min, $open) = $_[0]->{set}->min_a; | ||||
269 | return $open; | ||||
270 | } | ||||
271 | |||||
272 | sub start_is_closed { $_[0]->start_is_open ? 0 : 1 } | ||||
273 | |||||
274 | sub end_is_open { | ||||
275 | # max_a returns info about the set boundary | ||||
276 | my ($max, $open) = $_[0]->{set}->max_a; | ||||
277 | return $open; | ||||
278 | } | ||||
279 | |||||
280 | sub end_is_closed { $_[0]->end_is_open ? 0 : 1 } | ||||
281 | |||||
282 | |||||
283 | # span == $self | ||||
284 | sub span { @_ } | ||||
285 | |||||
286 | sub duration { | ||||
287 | my $dur; | ||||
288 | |||||
289 | local $@; | ||||
290 | eval { | ||||
291 | local $SIG{__DIE__}; # don't want to trap this (rt ticket 5434) | ||||
292 | $dur = $_[0]->end->subtract_datetime_absolute( $_[0]->start ) | ||||
293 | }; | ||||
294 | |||||
295 | return $dur if defined $dur; | ||||
296 | |||||
297 | return DateTime::Infinite::Future->new - | ||||
298 | DateTime::Infinite::Past->new; | ||||
299 | } | ||||
300 | 1 | 400ns | *size = \&duration; | ||
301 | |||||
302 | 1 | 5µs | 1; | ||
303 | |||||
304 | __END__ |