← Index
NYTProf Performance Profile   « block view • line view • sub view »
For 05.Domain_and_Item.t
  Run on Tue May 4 17:21:41 2010
Reported on Tue May 4 17:22:20 2010

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