DateTimeX-Lite
view release on metacpan or search on metacpan
lib/DateTimeX/Lite/Duration.pm view on Meta::CPAN
my %units = map { $_ => 1 } @units;
my %ret;
my ( $months, $days, $minutes, $seconds ) =
@{ $self }{qw( months days minutes seconds )};
if ( $units{years} )
{
$ret{years} = int( $months / 12 );
$months -= $ret{years} * 12;
}
if ( $units{months} )
{
$ret{months} = $months;
}
if ( $units{weeks} )
{
$ret{weeks} = int( $days / 7 );
$days -= $ret{weeks} * 7;
}
if ( $units{days} )
{
$ret{days} = $days;
}
if ( $units{hours} )
{
$ret{hours} = int( $minutes / 60 );
$minutes -= $ret{hours} * 60;
}
if ( $units{minutes} )
{
$ret{minutes} = $minutes
}
if ( $units{seconds} )
{
$ret{seconds} = $seconds;
$seconds = 0;
}
if ( $units{nanoseconds} )
{
$ret{nanoseconds} = $seconds * MAX_NANOSECONDS + $self->{nanoseconds};
}
wantarray ? @ret{@units} : $ret{ $units[0] };
}
sub is_wrap_mode { $_[0]->{end_of_month} eq 'wrap' ? 1 : 0 }
sub is_limit_mode { $_[0]->{end_of_month} eq 'limit' ? 1 : 0 }
sub is_preserve_mode { $_[0]->{end_of_month} eq 'preserve' ? 1 : 0 }
sub end_of_month_mode { $_[0]->{end_of_month} }
sub calendar_duration
{
my $self = shift;
return
(ref $self)->new( map { $_ => $self->{$_} } qw( months days end_of_month ) )
}
sub clock_duration
{
my $self = shift;
return
(ref $self)->new( map { $_ => $self->{$_} } qw( minutes seconds nanoseconds end_of_month ) )
}
sub inverse
{
my $self = shift;
my %new;
foreach my $u (@all_units)
{
$new{$u} = $self->{$u};
# avoid -0 bug
$new{$u} *= -1 if $new{$u};
}
return (ref $self)->new(%new);
}
sub add_duration
{
my ( $self, $dur ) = @_;
foreach my $u (@all_units)
{
$self->{$u} += $dur->{$u};
}
$self->_normalize_nanoseconds if $self->{nanoseconds};
return $self;
}
sub add
{
my $self = shift;
return $self->add_duration( (ref $self)->new(@_) );
}
sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) }
sub subtract
{
my $self = shift;
return $self->subtract_duration( (ref $self)->new(@_) )
}
lib/DateTimeX/Lite/Duration.pm view on Meta::CPAN
$dur->in_units( 'years', 'months' ); # (2, 3)
$dur->in_units( 'weeks', 'days' ); # (0, 0) !
The last example demonstrates that there will not be any conversion
between units which don't have a fixed conversion rate. The only
conversions possible are:
=over 8
=item * year <=> months
=item * weeks <=> days
=item * hours <=> minutes
=item * seconds <=> nanoseconds
=back
For the explanation of why this happens, please see the L<How Date
Math is Done|DateTimeX::Lite/"How Date Math is Done"> section of the
DateTimeX::Lite.pm documentation
Note that the numbers returned by this method may not match the values
given to the constructor.
In list context, in_units returns the lengths in the order of the units
given. In scalar context, it returns the length in the first unit (but
still computes in terms of all given units).
If you need more flexibility in presenting information about
durations, please take a look a C<DateTimeX::Lite::Format::Duration>.
=item * delta_months, delta_days, delta_minutes, delta_seconds, delta_nanoseconds
These methods provide the information C<DateTimeX::Lite.pm> needs for doing
date math. The numbers returned may be positive or negative.
=item * deltas
Returns a hash with the keys "months", "days", "minutes", "seconds",
and "nanoseconds", containing all the delta information for the
object.
=item * is_positive, is_zero, is_negative
Indicates whether or not the duration is positive, zero, or negative.
If the duration contains both positive and negative units, then it
will return false for B<all> of these methods.
=item * is_wrap_mode, is_limit_mode, is_preserve_mode
Indicates what mode is used for end of month wrapping.
=item * end_of_month_mode
Returns one of "wrap", "limit", or "preserve".
=item * calendar_duration
Returns a new object with the same I<calendar> delta (months and days
only) and end of month mode as the current object.
=item * clock_duration
Returns a new object with the same I<clock> deltas (minutes, seconds,
and nanoseconds) and end of month mode as the current object.
=item * inverse
Returns a new object with the same deltas as the current object, but
multiple by -1. The end of month mode for the new object will be the
default end of month mode, which depends on whether the new duration
is positive or negative.
=item * add_duration( $duration_object ), subtract_duration( $duration_object )
Adds or subtracts one duration from another.
=item * add( ... ), subtract( ... )
Syntactic sugar for addition and subtraction. The parameters given to
these methods are used to create a new object, which is then passed to
C<add_duration()> or C<subtract_duration()>, as appropriate.
=item * multiply( $number )
Multiplies each unit in the by the specified number.
=item * DateTimeX::Lite::Duration->compare( $duration1, $duration2, $base_datetime )
This is a class method that can be used to compare or sort durations.
Comparison is done by adding each duration to the specified
C<DateTimeX::Lite.pm> object and comparing the resulting datetimes. This is
necessary because without a base, many durations are not comparable.
For example, 1 month may otr may not be longer than 29 days, depending
on what datetime it is added to.
If no base datetime is given, then the result of C<< DateTimeX::Lite->now >>
is used instead. Using this default will give non-repeatable results
if used to compare two duration objects containing different units.
It will also give non-repeatable results if the durations contain
multiple types of units, such as months and days.
However, if you know that both objects only consist of one type of
unit (months I<or> days I<or> hours, etc.), and each duration contains
the same type of unit, then the results of the comparison will be
repeatable.
=item * years, months, weeks, days, hours, minutes, seconds, nanoseconds
These methods return numbers indicating how many of the given unit the
object represents, after having done a conversion to any larger units.
For example, days are first converted to weeks, and then the remainder
is returned. These numbers are always positive.
Here's what each method returns:
$dur->year() == abs( $dur->in_units('years') )
$dur->months() == ( abs( $dur->in_units( 'months', 'years' ) ) )[0]
$dur->weeks() == abs( $dur->in_units( 'weeks' ) )
( run in 3.104 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )