DateTime-Duration-Lite
view release on metacpan or search on metacpan
lib/DateTime/Duration/Lite.pm view on Meta::CPAN
my %units = map { $_ => 1 } @units;
my %ret;
my ( $months, $days, $minutes, $seconds )
= map { $self->$_ // 0 } 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 end_of_month {
my $e = $_[0]->_end_of_month;
$e eq 'w' ? 'wrap' :
$e eq 'l' ? 'limit' :
$e eq 'p' ? 'preserve' :
$e;
}
sub is_wrap_mode { $_[0]->end_of_month eq 'w' ? 1 : 0 }
sub is_limit_mode { $_[0]->end_of_month eq 'l' ? 1 : 0 }
sub is_preserve_mode { $_[0]->end_of_month eq 'p' ? 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 %p = @_;
my %new;
foreach my $u (@all_units) {
$new{$u} = $self->$u;
# avoid -0 bug
$new{$u} *= -1 if $new{$u};
}
$new{end_of_month} = $p{end_of_month}
if exists $p{end_of_month};
return ( ref $self )->new(%new);
}
sub add_duration {
my ( $self, $dur ) = @_;
foreach my $u (@all_units) {
my $meth = "_$u";
my $val = $dur->$meth;
next unless defined $val;
$self->$meth( ($self->$meth // 0) + $val );
}
$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(@_) );
}
( run in 1.759 second using v1.01-cache-2.11-cpan-39bf76dae61 )