DateTimeX-Lite
view release on metacpan or search on metacpan
lib/DateTimeX/Lite/Duration.pm view on Meta::CPAN
package DateTimeX::Lite::Duration;
use strict;
use warnings;
use Scalar::Util qw(blessed);
use Carp ();
use overload ( fallback => 1,
'+' => '_add_overload',
'-' => '_subtract_overload',
'*' => '_multiply_overload',
'<=>' => '_compare_overload',
'cmp' => '_compare_overload',
);
use constant MAX_NANOSECONDS => 1_000_000_000; # 1E9 = almost 32 bits
my @all_units = qw( months days minutes seconds nanoseconds );
# XXX - need to reject non-integers but accept infinity, NaN, &
# 1.56e+18
sub new
{
my ($class, %p) = @_;
foreach my $field (qw(years months weeks days hours minutes seconds nanoseconds)) {
$p{$field} = 0 unless defined $p{$field};
}
=head1
my %p = validate( @_,
{ years => { type => SCALAR, default => 0 },
months => { type => SCALAR, default => 0 },
weeks => { type => SCALAR, default => 0 },
days => { type => SCALAR, default => 0 },
hours => { type => SCALAR, default => 0 },
minutes => { type => SCALAR, default => 0 },
seconds => { type => SCALAR, default => 0 },
nanoseconds => { type => SCALAR, default => 0 },
end_of_month => { type => SCALAR, default => undef,
regex => qr/^(?:wrap|limit|preserve)$/ },
} );
=cut
my $self = bless {}, $class;
$self->{months} = ( $p{years} * 12 ) + $p{months};
$self->{days} = ( $p{weeks} * 7 ) + $p{days};
$self->{minutes} = ( $p{hours} * 60 ) + $p{minutes};
$self->{seconds} = $p{seconds};
if ( $p{nanoseconds} )
{
$self->{nanoseconds} = $p{nanoseconds};
$self->_normalize_nanoseconds;
}
else
{
# shortcut - if they don't need nanoseconds
$self->{nanoseconds} = 0;
}
$self->{end_of_month} =
( defined $p{end_of_month}
? $p{end_of_month}
: $self->{months} < 0
? 'preserve'
: 'wrap'
);
return $self;
}
# make the signs of seconds, nanos the same; 0 < abs(nanos) < MAX_NANOS
# NB this requires nanoseconds != 0 (callers check this already)
sub _normalize_nanoseconds
{
my $self = shift;
( run in 3.190 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )