Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/DateTime/Duration.pm |
Statements | Executed 28 statements in 1.60ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 15µs | 19µs | BEGIN@6 | DateTime::Duration::
1 | 1 | 1 | 10µs | 39µs | BEGIN@12 | DateTime::Duration::
1 | 1 | 1 | 10µs | 89µs | BEGIN@14 | DateTime::Duration::
1 | 1 | 1 | 9µs | 60µs | BEGIN@23 | DateTime::Duration::
1 | 1 | 1 | 9µs | 25µs | BEGIN@7 | DateTime::Duration::
1 | 1 | 1 | 8µs | 8µs | BEGIN@10 | DateTime::Duration::
1 | 1 | 1 | 5µs | 5µs | BEGIN@11 | DateTime::Duration::
1 | 1 | 1 | 3µs | 3µs | BEGIN@9 | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | _add_overload | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | _compare_overload | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | _has_negative | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | _has_positive | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | _multiply_overload | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | _normalize_nanoseconds | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | _subtract_overload | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | add | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | add_duration | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | calendar_duration | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | clock_duration | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | clone | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | compare | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | days | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | delta_days | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | delta_minutes | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | delta_months | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | delta_nanoseconds | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | delta_seconds | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | deltas | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | end_of_month_mode | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | hours | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | in_units | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | inverse | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | is_limit_mode | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | is_negative | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | is_positive | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | is_preserve_mode | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | is_wrap_mode | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | is_zero | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | minutes | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | months | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | multiply | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | nanoseconds | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | new | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | seconds | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | subtract | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | subtract_duration | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | weeks | DateTime::Duration::
0 | 0 | 0 | 0s | 0s | years | DateTime::Duration::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package DateTime::Duration; | ||||
2 | { | ||||
3 | 2 | 1µs | $DateTime::Duration::VERSION = '0.74'; | ||
4 | } | ||||
5 | |||||
6 | 3 | 20µs | 2 | 24µs | # spent 19µs (15+4) within DateTime::Duration::BEGIN@6 which was called:
# once (15µs+4µs) by DateTime::BEGIN@46 at line 6 # spent 19µs making 1 call to DateTime::Duration::BEGIN@6
# spent 4µs making 1 call to strict::import |
7 | 3 | 18µs | 2 | 42µs | # spent 25µs (9+16) within DateTime::Duration::BEGIN@7 which was called:
# once (9µs+16µs) by DateTime::BEGIN@46 at line 7 # spent 25µs making 1 call to DateTime::Duration::BEGIN@7
# spent 16µs making 1 call to warnings::import |
8 | |||||
9 | 3 | 15µs | 1 | 3µs | # spent 3µs within DateTime::Duration::BEGIN@9 which was called:
# once (3µs+0s) by DateTime::BEGIN@46 at line 9 # spent 3µs making 1 call to DateTime::Duration::BEGIN@9 |
10 | 3 | 21µs | 1 | 8µs | # spent 8µs within DateTime::Duration::BEGIN@10 which was called:
# once (8µs+0s) by DateTime::BEGIN@46 at line 10 # spent 8µs making 1 call to DateTime::Duration::BEGIN@10 |
11 | 3 | 22µs | 1 | 5µs | # spent 5µs within DateTime::Duration::BEGIN@11 which was called:
# once (5µs+0s) by DateTime::BEGIN@46 at line 11 # spent 5µs making 1 call to DateTime::Duration::BEGIN@11 |
12 | 3 | 33µs | 2 | 68µs | # spent 39µs (10+29) within DateTime::Duration::BEGIN@12 which was called:
# once (10µs+29µs) by DateTime::BEGIN@46 at line 12 # spent 39µs making 1 call to DateTime::Duration::BEGIN@12
# spent 29µs making 1 call to Exporter::import |
13 | |||||
14 | # spent 89µs (10+79) within DateTime::Duration::BEGIN@14 which was called:
# once (10µs+79µs) by DateTime::BEGIN@46 at line 21 | ||||
15 | 1 | 79µs | fallback => 1, # spent 79µs making 1 call to overload::import | ||
16 | '+' => '_add_overload', | ||||
17 | '-' => '_subtract_overload', | ||||
18 | '*' => '_multiply_overload', | ||||
19 | '<=>' => '_compare_overload', | ||||
20 | 'cmp' => '_compare_overload', | ||||
21 | 3 | 23µs | 1 | 89µs | ); # spent 89µs making 1 call to DateTime::Duration::BEGIN@14 |
22 | |||||
23 | 3 | 1.44ms | 2 | 110µs | # spent 60µs (9+51) within DateTime::Duration::BEGIN@23 which was called:
# once (9µs+51µs) by DateTime::BEGIN@46 at line 23 # spent 60µs making 1 call to DateTime::Duration::BEGIN@23
# spent 51µs making 1 call to constant::import |
24 | |||||
25 | 1 | 2µs | my @all_units = qw( months days minutes seconds nanoseconds ); | ||
26 | |||||
27 | # XXX - need to reject non-integers but accept infinity, NaN, & | ||||
28 | # 1.56e+18 | ||||
29 | sub new { | ||||
30 | my $class = shift; | ||||
31 | my %p = validate( | ||||
32 | @_, { | ||||
33 | years => { type => SCALAR, default => 0 }, | ||||
34 | months => { type => SCALAR, default => 0 }, | ||||
35 | weeks => { type => SCALAR, default => 0 }, | ||||
36 | days => { type => SCALAR, default => 0 }, | ||||
37 | hours => { type => SCALAR, default => 0 }, | ||||
38 | minutes => { type => SCALAR, default => 0 }, | ||||
39 | seconds => { type => SCALAR, default => 0 }, | ||||
40 | nanoseconds => { type => SCALAR, default => 0 }, | ||||
41 | end_of_month => { | ||||
42 | type => SCALAR, default => undef, | ||||
43 | regex => qr/^(?:wrap|limit|preserve)$/ | ||||
44 | }, | ||||
45 | } | ||||
46 | ); | ||||
47 | |||||
48 | my $self = bless {}, $class; | ||||
49 | |||||
50 | $self->{months} = ( $p{years} * 12 ) + $p{months}; | ||||
51 | |||||
52 | $self->{days} = ( $p{weeks} * 7 ) + $p{days}; | ||||
53 | |||||
54 | $self->{minutes} = ( $p{hours} * 60 ) + $p{minutes}; | ||||
55 | |||||
56 | $self->{seconds} = $p{seconds}; | ||||
57 | |||||
58 | if ( $p{nanoseconds} ) { | ||||
59 | $self->{nanoseconds} = $p{nanoseconds}; | ||||
60 | $self->_normalize_nanoseconds; | ||||
61 | } | ||||
62 | else { | ||||
63 | |||||
64 | # shortcut - if they don't need nanoseconds | ||||
65 | $self->{nanoseconds} = 0; | ||||
66 | } | ||||
67 | |||||
68 | $self->{end_of_month} = ( | ||||
69 | defined $p{end_of_month} ? $p{end_of_month} | ||||
70 | : $self->{months} < 0 ? 'preserve' | ||||
71 | : 'wrap' | ||||
72 | ); | ||||
73 | |||||
74 | return $self; | ||||
75 | } | ||||
76 | |||||
77 | # make the signs of seconds, nanos the same; 0 < abs(nanos) < MAX_NANOS | ||||
78 | # NB this requires nanoseconds != 0 (callers check this already) | ||||
79 | sub _normalize_nanoseconds { | ||||
80 | my $self = shift; | ||||
81 | |||||
82 | return | ||||
83 | if ( $self->{nanoseconds} == DateTime::INFINITY() | ||||
84 | || $self->{nanoseconds} == DateTime::NEG_INFINITY() | ||||
85 | || $self->{nanoseconds} eq DateTime::NAN() ); | ||||
86 | |||||
87 | my $seconds = $self->{seconds} + $self->{nanoseconds} / MAX_NANOSECONDS; | ||||
88 | $self->{seconds} = int($seconds); | ||||
89 | $self->{nanoseconds} = $self->{nanoseconds} % MAX_NANOSECONDS; | ||||
90 | $self->{nanoseconds} -= MAX_NANOSECONDS if $seconds < 0; | ||||
91 | } | ||||
92 | |||||
93 | sub clone { bless { %{ $_[0] } }, ref $_[0] } | ||||
94 | |||||
95 | sub years { abs( $_[0]->in_units('years') ) } | ||||
96 | sub months { abs( $_[0]->in_units( 'months', 'years' ) ) } | ||||
97 | sub weeks { abs( $_[0]->in_units('weeks') ) } | ||||
98 | sub days { abs( $_[0]->in_units( 'days', 'weeks' ) ) } | ||||
99 | sub hours { abs( $_[0]->in_units('hours') ) } | ||||
100 | sub minutes { abs( $_[0]->in_units( 'minutes', 'hours' ) ) } | ||||
101 | sub seconds { abs( $_[0]->in_units('seconds') ) } | ||||
102 | sub nanoseconds { abs( $_[0]->in_units( 'nanoseconds', 'seconds' ) ) } | ||||
103 | |||||
104 | sub is_positive { $_[0]->_has_positive && !$_[0]->_has_negative } | ||||
105 | sub is_negative { !$_[0]->_has_positive && $_[0]->_has_negative } | ||||
106 | |||||
107 | sub _has_positive { | ||||
108 | ( grep { $_ > 0 } @{ $_[0] }{@all_units} ) ? 1 : 0; | ||||
109 | } | ||||
110 | |||||
111 | sub _has_negative { | ||||
112 | ( grep { $_ < 0 } @{ $_[0] }{@all_units} ) ? 1 : 0; | ||||
113 | } | ||||
114 | |||||
115 | sub is_zero { | ||||
116 | return 0 if grep { $_ != 0 } @{ $_[0] }{@all_units}; | ||||
117 | return 1; | ||||
118 | } | ||||
119 | |||||
120 | sub delta_months { $_[0]->{months} } | ||||
121 | sub delta_days { $_[0]->{days} } | ||||
122 | sub delta_minutes { $_[0]->{minutes} } | ||||
123 | sub delta_seconds { $_[0]->{seconds} } | ||||
124 | sub delta_nanoseconds { $_[0]->{nanoseconds} } | ||||
125 | |||||
126 | sub deltas { | ||||
127 | map { $_ => $_[0]->{$_} } @all_units; | ||||
128 | } | ||||
129 | |||||
130 | sub in_units { | ||||
131 | my $self = shift; | ||||
132 | my @units = @_; | ||||
133 | |||||
134 | my %units = map { $_ => 1 } @units; | ||||
135 | |||||
136 | my %ret; | ||||
137 | |||||
138 | my ( $months, $days, $minutes, $seconds ) | ||||
139 | = @{$self}{qw( months days minutes seconds )}; | ||||
140 | |||||
141 | if ( $units{years} ) { | ||||
142 | $ret{years} = int( $months / 12 ); | ||||
143 | $months -= $ret{years} * 12; | ||||
144 | } | ||||
145 | |||||
146 | if ( $units{months} ) { | ||||
147 | $ret{months} = $months; | ||||
148 | } | ||||
149 | |||||
150 | if ( $units{weeks} ) { | ||||
151 | $ret{weeks} = int( $days / 7 ); | ||||
152 | $days -= $ret{weeks} * 7; | ||||
153 | } | ||||
154 | |||||
155 | if ( $units{days} ) { | ||||
156 | $ret{days} = $days; | ||||
157 | } | ||||
158 | |||||
159 | if ( $units{hours} ) { | ||||
160 | $ret{hours} = int( $minutes / 60 ); | ||||
161 | $minutes -= $ret{hours} * 60; | ||||
162 | } | ||||
163 | |||||
164 | if ( $units{minutes} ) { | ||||
165 | $ret{minutes} = $minutes; | ||||
166 | } | ||||
167 | |||||
168 | if ( $units{seconds} ) { | ||||
169 | $ret{seconds} = $seconds; | ||||
170 | $seconds = 0; | ||||
171 | } | ||||
172 | |||||
173 | if ( $units{nanoseconds} ) { | ||||
174 | $ret{nanoseconds} = $seconds * MAX_NANOSECONDS + $self->{nanoseconds}; | ||||
175 | } | ||||
176 | |||||
177 | wantarray ? @ret{@units} : $ret{ $units[0] }; | ||||
178 | } | ||||
179 | |||||
180 | sub is_wrap_mode { $_[0]->{end_of_month} eq 'wrap' ? 1 : 0 } | ||||
181 | sub is_limit_mode { $_[0]->{end_of_month} eq 'limit' ? 1 : 0 } | ||||
182 | sub is_preserve_mode { $_[0]->{end_of_month} eq 'preserve' ? 1 : 0 } | ||||
183 | |||||
184 | sub end_of_month_mode { $_[0]->{end_of_month} } | ||||
185 | |||||
186 | sub calendar_duration { | ||||
187 | my $self = shift; | ||||
188 | |||||
189 | return ( ref $self ) | ||||
190 | ->new( map { $_ => $self->{$_} } qw( months days end_of_month ) ); | ||||
191 | } | ||||
192 | |||||
193 | sub clock_duration { | ||||
194 | my $self = shift; | ||||
195 | |||||
196 | return ( ref $self ) | ||||
197 | ->new( map { $_ => $self->{$_} } | ||||
198 | qw( minutes seconds nanoseconds end_of_month ) ); | ||||
199 | } | ||||
200 | |||||
201 | sub inverse { | ||||
202 | my $self = shift; | ||||
203 | my %p = @_; | ||||
204 | |||||
205 | my %new; | ||||
206 | foreach my $u (@all_units) { | ||||
207 | $new{$u} = $self->{$u}; | ||||
208 | |||||
209 | # avoid -0 bug | ||||
210 | $new{$u} *= -1 if $new{$u}; | ||||
211 | } | ||||
212 | |||||
213 | $new{end_of_month} = $p{end_of_month} | ||||
214 | if exists $p{end_of_month}; | ||||
215 | |||||
216 | return ( ref $self )->new(%new); | ||||
217 | } | ||||
218 | |||||
219 | sub add_duration { | ||||
220 | my ( $self, $dur ) = @_; | ||||
221 | |||||
222 | foreach my $u (@all_units) { | ||||
223 | $self->{$u} += $dur->{$u}; | ||||
224 | } | ||||
225 | |||||
226 | $self->_normalize_nanoseconds if $self->{nanoseconds}; | ||||
227 | |||||
228 | return $self; | ||||
229 | } | ||||
230 | |||||
231 | sub add { | ||||
232 | my $self = shift; | ||||
233 | |||||
234 | return $self->add_duration( ( ref $self )->new(@_) ); | ||||
235 | } | ||||
236 | |||||
237 | sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) } | ||||
238 | |||||
239 | sub subtract { | ||||
240 | my $self = shift; | ||||
241 | |||||
242 | return $self->subtract_duration( ( ref $self )->new(@_) ); | ||||
243 | } | ||||
244 | |||||
245 | sub multiply { | ||||
246 | my $self = shift; | ||||
247 | my $multiplier = shift; | ||||
248 | |||||
249 | foreach my $u (@all_units) { | ||||
250 | $self->{$u} *= $multiplier; | ||||
251 | } | ||||
252 | |||||
253 | $self->_normalize_nanoseconds if $self->{nanoseconds}; | ||||
254 | |||||
255 | return $self; | ||||
256 | } | ||||
257 | |||||
258 | sub compare { | ||||
259 | my ( $class, $dur1, $dur2, $dt ) = @_; | ||||
260 | |||||
261 | $dt ||= DateTime->now; | ||||
262 | |||||
263 | return DateTime->compare( $dt->clone->add_duration($dur1), | ||||
264 | $dt->clone->add_duration($dur2) ); | ||||
265 | } | ||||
266 | |||||
267 | sub _add_overload { | ||||
268 | my ( $d1, $d2, $rev ) = @_; | ||||
269 | |||||
270 | ( $d1, $d2 ) = ( $d2, $d1 ) if $rev; | ||||
271 | |||||
272 | if ( DateTime::Helpers::isa( $d2, 'DateTime' ) ) { | ||||
273 | $d2->add_duration($d1); | ||||
274 | return; | ||||
275 | } | ||||
276 | |||||
277 | # will also work if $d1 is a DateTime.pm object | ||||
278 | return $d1->clone->add_duration($d2); | ||||
279 | } | ||||
280 | |||||
281 | sub _subtract_overload { | ||||
282 | my ( $d1, $d2, $rev ) = @_; | ||||
283 | |||||
284 | ( $d1, $d2 ) = ( $d2, $d1 ) if $rev; | ||||
285 | |||||
286 | Carp::croak( | ||||
287 | "Cannot subtract a DateTime object from a DateTime::Duration object") | ||||
288 | if DateTime::Helpers::isa( $d2, 'DateTime' ); | ||||
289 | |||||
290 | return $d1->clone->subtract_duration($d2); | ||||
291 | } | ||||
292 | |||||
293 | sub _multiply_overload { | ||||
294 | my $self = shift; | ||||
295 | |||||
296 | my $new = $self->clone; | ||||
297 | |||||
298 | return $new->multiply(@_); | ||||
299 | } | ||||
300 | |||||
301 | sub _compare_overload { | ||||
302 | Carp::croak( 'DateTime::Duration does not overload comparison.' | ||||
303 | . ' See the documentation on the compare() method for details.' | ||||
304 | ); | ||||
305 | } | ||||
306 | |||||
307 | 1 | 4µs | 1; | ||
308 | |||||
309 | # ABSTRACT: Duration objects for date math | ||||
310 | |||||
- - | |||||
313 | =pod | ||||
314 | |||||
315 | =head1 NAME | ||||
316 | |||||
317 | DateTime::Duration - Duration objects for date math | ||||
318 | |||||
319 | =head1 VERSION | ||||
320 | |||||
321 | version 0.74 | ||||
322 | |||||
323 | =head1 SYNOPSIS | ||||
324 | |||||
325 | use DateTime::Duration; | ||||
326 | |||||
327 | $dur = DateTime::Duration->new( | ||||
328 | years => 3, | ||||
329 | months => 5, | ||||
330 | weeks => 1, | ||||
331 | days => 1, | ||||
332 | hours => 6, | ||||
333 | minutes => 15, | ||||
334 | seconds => 45, | ||||
335 | nanoseconds => 12000 | ||||
336 | ); | ||||
337 | |||||
338 | my ( $days, $hours, $seconds ) = $dur->in_units('days', 'hours', 'seconds'); | ||||
339 | |||||
340 | # Human-readable accessors, always positive, but consider using | ||||
341 | # DateTime::Format::Duration instead | ||||
342 | $dur->years; | ||||
343 | $dur->months; | ||||
344 | $dur->weeks; | ||||
345 | $dur->days; | ||||
346 | $dur->hours; | ||||
347 | $dur->minutes; | ||||
348 | $dur->seconds; | ||||
349 | $dur->nanoseconds; | ||||
350 | |||||
351 | $dur->is_wrap_mode | ||||
352 | $dur->is_limit_mode | ||||
353 | $dur->is_preserve_mode | ||||
354 | |||||
355 | print $dur->end_of_month_mode; | ||||
356 | |||||
357 | # Multiply all values by -1 | ||||
358 | my $opposite = $dur->inverse; | ||||
359 | |||||
360 | my $bigger = $dur1 + $dur2; | ||||
361 | my $smaller = $dur1 - $dur2; # the result could be negative | ||||
362 | my $bigger = $dur1 * 3; | ||||
363 | |||||
364 | my $base_dt = DateTime->new( year => 2000 ); | ||||
365 | my @sorted = | ||||
366 | sort { DateTime::Duration->compare( $a, $b, $base_dt ) } @durations; | ||||
367 | |||||
368 | if ( $dur->is_positive ) { ... } | ||||
369 | if ( $dur->is_zero ) { ... } | ||||
370 | if ( $dur->is_negative ) { ... } | ||||
371 | |||||
372 | =head1 DESCRIPTION | ||||
373 | |||||
374 | This is a simple class for representing duration objects. These | ||||
375 | objects are used whenever you do date math with DateTime.pm. | ||||
376 | |||||
377 | See the L<How Date Math is Done|DateTime/"How Date Math is Done"> | ||||
378 | section of the DateTime.pm documentation for more details. The short | ||||
379 | course: One cannot in general convert between seconds, minutes, days, | ||||
380 | and months, so this class will never do so. Instead, create the | ||||
381 | duration with the desired units to begin with, for example by calling | ||||
382 | the appropriate subtraction/delta method on a C<DateTime.pm> object. | ||||
383 | |||||
384 | =head1 METHODS | ||||
385 | |||||
386 | Like C<DateTime> itself, C<DateTime::Duration> returns the object from | ||||
387 | mutator methods in order to make method chaining possible. | ||||
388 | |||||
389 | C<DateTime::Duration> has the following methods: | ||||
390 | |||||
391 | =over 4 | ||||
392 | |||||
393 | =item * new( ... ) | ||||
394 | |||||
395 | This method takes the parameters "years", "months", "weeks", "days", | ||||
396 | "hours", "minutes", "seconds", "nanoseconds", and "end_of_month". All | ||||
397 | of these except "end_of_month" are numbers. If any of the numbers are | ||||
398 | negative, the entire duration is negative. | ||||
399 | |||||
400 | All of the numbers B<must be integers>. | ||||
401 | |||||
402 | Internally, years as just treated as 12 months. Similarly, weeks are | ||||
403 | treated as 7 days, and hours are converted to minutes. Seconds and | ||||
404 | nanoseconds are both treated separately. | ||||
405 | |||||
406 | The "end_of_month" parameter must be either "wrap", "limit", or | ||||
407 | "preserve". This parameter specifies how date math that crosses the | ||||
408 | end of a month is handled. | ||||
409 | |||||
410 | In "wrap" mode, adding months or years that result in days beyond the | ||||
411 | end of the new month will roll over into the following month. For | ||||
412 | instance, adding one year to Feb 29 will result in Mar 1. | ||||
413 | |||||
414 | If you specify "end_of_month" mode as "limit", the end of the month is | ||||
415 | never crossed. Thus, adding one year to Feb 29, 2000 will result in | ||||
416 | Feb 28, 2001. If you were to then add three more years this will | ||||
417 | result in Feb 28, 2004. | ||||
418 | |||||
419 | If you specify "end_of_month" mode as "preserve", the same calculation | ||||
420 | is done as for "limit" except that if the original date is at the end | ||||
421 | of the month the new date will also be. For instance, adding one | ||||
422 | month to Feb 29, 2000 will result in Mar 31, 2000. | ||||
423 | |||||
424 | For positive durations, the "end_of_month" parameter defaults to wrap. | ||||
425 | For negative durations, the default is "limit". This should match how | ||||
426 | most people "intuitively" expect datetime math to work. | ||||
427 | |||||
428 | =item * clone | ||||
429 | |||||
430 | Returns a new object with the same properties as the object on which | ||||
431 | this method was called. | ||||
432 | |||||
433 | =item * in_units( ... ) | ||||
434 | |||||
435 | Returns the length of the duration in the units (any of those that can | ||||
436 | be passed to C<new>) given as arguments. All lengths are integral, | ||||
437 | but may be negative. Smaller units are computed from what remains | ||||
438 | after taking away the larger units given, so for example: | ||||
439 | |||||
440 | my $dur = DateTime::Duration->new( years => 1, months => 15 ); | ||||
441 | |||||
442 | $dur->in_units( 'years' ); # 2 | ||||
443 | $dur->in_units( 'months' ); # 27 | ||||
444 | $dur->in_units( 'years', 'months' ); # (2, 3) | ||||
445 | $dur->in_units( 'weeks', 'days' ); # (0, 0) ! | ||||
446 | |||||
447 | The last example demonstrates that there will not be any conversion | ||||
448 | between units which don't have a fixed conversion rate. The only | ||||
449 | conversions possible are: | ||||
450 | |||||
451 | =over 8 | ||||
452 | |||||
453 | =item * years <=> months | ||||
454 | |||||
455 | =item * weeks <=> days | ||||
456 | |||||
457 | =item * hours <=> minutes | ||||
458 | |||||
459 | =item * seconds <=> nanoseconds | ||||
460 | |||||
461 | =back | ||||
462 | |||||
463 | For the explanation of why this is the case, please see the L<How Datetime | ||||
464 | Math Works|DateTime/"How DateTime Math Works"> section of the DateTime.pm | ||||
465 | documentation | ||||
466 | |||||
467 | Note that the numbers returned by this method may not match the values | ||||
468 | given to the constructor. | ||||
469 | |||||
470 | In list context, in_units returns the lengths in the order of the units | ||||
471 | given. In scalar context, it returns the length in the first unit (but | ||||
472 | still computes in terms of all given units). | ||||
473 | |||||
474 | If you need more flexibility in presenting information about | ||||
475 | durations, please take a look a C<DateTime::Format::Duration>. | ||||
476 | |||||
477 | =item * is_positive, is_zero, is_negative | ||||
478 | |||||
479 | Indicates whether or not the duration is positive, zero, or negative. | ||||
480 | |||||
481 | If the duration contains both positive and negative units, then it | ||||
482 | will return false for B<all> of these methods. | ||||
483 | |||||
484 | =item * is_wrap_mode, is_limit_mode, is_preserve_mode | ||||
485 | |||||
486 | Indicates what mode is used for end of month wrapping. | ||||
487 | |||||
488 | =item * end_of_month_mode | ||||
489 | |||||
490 | Returns one of "wrap", "limit", or "preserve". | ||||
491 | |||||
492 | =item * calendar_duration | ||||
493 | |||||
494 | Returns a new object with the same I<calendar> delta (months and days | ||||
495 | only) and end of month mode as the current object. | ||||
496 | |||||
497 | =item * clock_duration | ||||
498 | |||||
499 | Returns a new object with the same I<clock> deltas (minutes, seconds, | ||||
500 | and nanoseconds) and end of month mode as the current object. | ||||
501 | |||||
502 | =item * inverse( ... ) | ||||
503 | |||||
504 | Returns a new object with the same deltas as the current object, but | ||||
505 | multiple by -1. The end of month mode for the new object will be the | ||||
506 | default end of month mode, which depends on whether the new duration | ||||
507 | is positive or negative. | ||||
508 | |||||
509 | You can set the end of month mode in the inverted duration explicitly by | ||||
510 | passing "end_of_month => ..." to the C<inverse()> method. | ||||
511 | |||||
512 | =item * add_duration( $duration_object ), subtract_duration( $duration_object ) | ||||
513 | |||||
514 | Adds or subtracts one duration from another. | ||||
515 | |||||
516 | =item * add( ... ), subtract( ... ) | ||||
517 | |||||
518 | Syntactic sugar for addition and subtraction. The parameters given to | ||||
519 | these methods are used to create a new object, which is then passed to | ||||
520 | C<add_duration()> or C<subtract_duration()>, as appropriate. | ||||
521 | |||||
522 | =item * multiply( $number ) | ||||
523 | |||||
524 | Multiplies each unit in the by the specified number. | ||||
525 | |||||
526 | =item * DateTime::Duration->compare( $duration1, $duration2, $base_datetime ) | ||||
527 | |||||
528 | This is a class method that can be used to compare or sort durations. | ||||
529 | Comparison is done by adding each duration to the specified | ||||
530 | C<DateTime.pm> object and comparing the resulting datetimes. This is | ||||
531 | necessary because without a base, many durations are not comparable. | ||||
532 | For example, 1 month may or may not be longer than 29 days, depending | ||||
533 | on what datetime it is added to. | ||||
534 | |||||
535 | If no base datetime is given, then the result of C<< DateTime->now >> | ||||
536 | is used instead. Using this default will give non-repeatable results | ||||
537 | if used to compare two duration objects containing different units. | ||||
538 | It will also give non-repeatable results if the durations contain | ||||
539 | multiple types of units, such as months and days. | ||||
540 | |||||
541 | However, if you know that both objects only consist of one type of | ||||
542 | unit (months I<or> days I<or> hours, etc.), and each duration contains | ||||
543 | the same type of unit, then the results of the comparison will be | ||||
544 | repeatable. | ||||
545 | |||||
546 | =item * delta_months, delta_days, delta_minutes, delta_seconds, delta_nanoseconds | ||||
547 | |||||
548 | These methods provide the information C<DateTime.pm> needs for doing date | ||||
549 | math. The numbers returned may be positive or negative. This is mostly useful | ||||
550 | for doing date math in L<DateTime>. | ||||
551 | |||||
552 | =item * deltas | ||||
553 | |||||
554 | Returns a hash with the keys "months", "days", "minutes", "seconds", and | ||||
555 | "nanoseconds", containing all the delta information for the object. This is | ||||
556 | mostly useful for doing date math in L<DateTime>. | ||||
557 | |||||
558 | =item * years, months, weeks, days, hours, minutes, seconds, nanoseconds | ||||
559 | |||||
560 | These methods return numbers indicating how many of the given unit the | ||||
561 | object represents, after having done a conversion to any larger units. | ||||
562 | For example, days are first converted to weeks, and then the remainder | ||||
563 | is returned. These numbers are always positive. | ||||
564 | |||||
565 | Here's what each method returns: | ||||
566 | |||||
567 | $dur->years() == abs( $dur->in_units('years') ) | ||||
568 | $dur->months() == abs( ( $dur->in_units( 'months', 'years' ) )[0] ) | ||||
569 | $dur->weeks() == abs( $dur->in_units( 'weeks' ) ) | ||||
570 | $dur->days() == abs( ( $dur->in_units( 'days', 'weeks' ) )[0] ) | ||||
571 | $dur->hours() == abs( $dur->in_units( 'hours' ) ) | ||||
572 | $dur->minutes == abs( ( $dur->in_units( 'minutes', 'hours' ) )[0] ) | ||||
573 | $dur->seconds == abs( $dur->in_units( 'seconds' ) ) | ||||
574 | $dur->nanoseconds() == abs( ( $dur->in_units( 'nanoseconds', 'seconds' ) )[0] ) | ||||
575 | |||||
576 | If this seems confusing, remember that you can always use the | ||||
577 | C<in_units()> method to specify exactly what you want. | ||||
578 | |||||
579 | Better yet, if you are trying to generate output suitable for humans, | ||||
580 | use the C<DateTime::Format::Duration> module. | ||||
581 | |||||
582 | =back | ||||
583 | |||||
584 | =head2 Overloading | ||||
585 | |||||
586 | This class overloads addition, subtraction, and mutiplication. | ||||
587 | |||||
588 | Comparison is B<not> overloaded. If you attempt to compare durations | ||||
589 | using C<< <=> >> or C<cmp>, then an exception will be thrown! Use the | ||||
590 | C<compare()> class method instead. | ||||
591 | |||||
592 | =head1 SUPPORT | ||||
593 | |||||
594 | Support for this module is provided via the datetime@perl.org email | ||||
595 | list. See http://lists.perl.org/ for more details. | ||||
596 | |||||
597 | =head1 SEE ALSO | ||||
598 | |||||
599 | datetime@perl.org mailing list | ||||
600 | |||||
601 | http://datetime.perl.org/ | ||||
602 | |||||
603 | =head1 AUTHOR | ||||
604 | |||||
605 | Dave Rolsky <autarch@urth.org> | ||||
606 | |||||
607 | =head1 COPYRIGHT AND LICENSE | ||||
608 | |||||
609 | This software is Copyright (c) 2012 by Dave Rolsky. | ||||
610 | |||||
611 | This is free software, licensed under: | ||||
612 | |||||
613 | The Artistic License 2.0 (GPL Compatible) | ||||
614 | |||||
615 | =cut | ||||
616 | |||||
617 | |||||
618 | __END__ |