Badger

 view release on metacpan or  search on metacpan

lib/Badger/Period.pm  view on Meta::CPAN

package Badger::Period;

use Badger::Class
    version   => 0.01,
    debug     => 0,
    base      => 'Badger::Comparable',
    utils     => 'numlike is_object',
    accessors => 'uri',
    as_text   => 'uri',
    is_true   => 1,
    constants => 'HASH ARRAY DELIMITER',
    constant  => {
        FIELD_NAMES => undef,
        TYPE_NAME   => 'period',
    },
    messages  => {
        bad_type      => 'Invalid %s: %s',
        bad_duration  => 'Invalid duration: %s',
    };

use Time::Local;
use POSIX 'strftime';

our @YMD        = qw( year month day );
our @HMS        = qw( hour minute second );
our @SMHD       = qw( second minute hour day );
our @YMDHMS     = (@YMD, @HMS);
our $SECONDS    = {
    s => 1,
    m => 60,
    h => 60*60,
    d => 60*60*24,
    M => 60*60*24*30,
    y => 60*60*24*365,
};


sub split_regex {
    shift->not_implemented;
}


sub join_format {
    shift->not_implemented;
}


sub text_format {
    shift->join_format;
}


sub field_names {
    my $class = shift;
    my $names = $class->FIELD_NAMES
        || return $class->not_implemented;

    $names = [ split(DELIMITER, $names) ] 
        unless ref $names eq ARRAY;

    return wantarray
        ?  @$names
        : \@$names
}


#-----------------------------------------------------------------------
# Methods
#-----------------------------------------------------------------------

sub new {
    my $class  = shift; 
    my @fields = $class->field_names;
    my $self   = bless { map { ($_, 0) } @fields }, ref $class || $class;
    my ($config, $time);
    
    if (@_ > 1) {
        # multiple arguments are named params
        $config = { @_ };
    }
    elsif (@_ == 1 && defined $_[0]) {
        # single argument is a hash of named params, a timestamp or time in
        # seconds since the epoch
        $config = ref $_[0] eq HASH ? shift : { time => shift };
    }
    # otherwise we default to now
    else {
        $config = { time => time() };
    }

    if ($time = $config->{ time }) {
        if (numlike $time) {
            # $time is seconds since epoch
            (@$config{ @YMDHMS }) = reverse( ( localtime($time) )[0..5] );
            $config->{ year  }+= 1900;
            $config->{ month }++;
            $config->{ etime } = $time;
        }
        elsif (is_object(ref $class || $class, $time)) {
            $config->{ uri   } = $time->uri;
            $config->{ etime } = $time->epoch_time;
            $self->split_uri($config->{ uri }, $config);
        }
        else {
            # $time is a timestamp so split and rejoin into canonical form
            $config->{ uri } = $time;
            $self->split_uri($config);
        }
        $self->join_uri($config);
    }

    # set any fields defined in config, allowing singular (second,month,
    # etc) and plural (seconds, months, etc)
    foreach my $field (@fields) {
        $self->{ $field } = $config->{ $field } || $config->{"${field}s"} || 0;
    }



( run in 0.748 second using v1.01-cache-2.11-cpan-98e64b0badf )