File Coverage

blib/lib/Date/Calc/Iterator.pm
Criterion Covered Total %
statement 66 70 94.2
branch 18 26 69.2
condition 2 6 33.3
subroutine 13 13 100.0
pod 2 2 100.0
total 101 117 86.3


line stmt bran cond sub pod time code
1             package Date::Calc::Iterator;
2              
3 2     2   158510 use 5.006;
  2         18  
4 2     2   11 use strict;
  2         4  
  2         51  
5 2     2   9 use warnings;
  2         4  
  2         109  
6              
7             our $VERSION = '1.02';
8              
9 2     2   875 use Date::Calc qw( Delta_Days Add_Delta_Days check_date ) ;
  2         15688  
  2         169  
10 2     2   1068 use Ref::Util qw( is_arrayref is_ref );
  2         3629  
  2         149  
11 2     2   19 use Carp qw( croak );
  2         3  
  2         129  
12              
13 2     2   15 use constant FORMAT_ARRAYREF => 1;
  2         3  
  2         187  
14 2     2   11 use constant FORMAT_ISO_DASHED => 2;
  2         5  
  2         74  
15 2     2   10 use constant FORMAT_ISO_NO_DASH => 3;
  2         4  
  2         80  
16              
17 2     2   29 use constant DEFAULT_STEP_SIZE => 1;
  2         3  
  2         1278  
18              
19             sub new {
20 8     8 1 3448 my $self = shift ;
21 8         28 my %parms = @_ ;
22              
23 8   33     38 my $class = ref $self || $self ;
24              
25 8         36 my ($from, $from_format) = _validate_date_param(\%parms, 'from');
26 8         20 my ($to, $to_format) = _validate_date_param(\%parms, 'to');
27              
28             # TODO: should we require that the from format matches the to format?
29              
30 8 50 33     39 if (exists($parms{step}) && $parms{step} !~ /^\d+$/) {
31 0         0 croak "the 'step' parameter must be an integer";
32             }
33              
34 8         31 my $object = {
35             from => $from,
36             to => $to,
37             format => $from_format,
38             delta => 0,
39             };
40              
41 8 50       19 $object->{step} = exists($parms{step}) ? $parms{step} : DEFAULT_STEP_SIZE;
42 8         12 $object->{maxdelta} = Delta_Days(@{$from}, @{$to}) ;
  8         11  
  8         28  
43              
44 8         33 return bless($object, $class);
45             }
46              
47             sub _validate_date_param
48             {
49 16     16   31 my ($params, $key) = @_;
50 16         43 my $date = $params->{$key};
51 16         20 my $ymdref;
52             my $format;
53              
54 16 50       32 croak "you must provide a '$key' date" unless defined($date);
55              
56 16 100       68 if (is_arrayref($date)) {
    50          
    100          
    50          
57 4         5 $ymdref = $date;
58 4         5 $format = FORMAT_ARRAYREF;
59             }
60             elsif (is_ref($date)) {
61 0         0 croak "unexpected reference type for '$key' parameter";
62             }
63             # TODO: should probably make these [0-9] instead of \d
64             elsif ($date =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/) {
65 6         20 $ymdref = [$1, $2, $3];
66 6         10 $format = FORMAT_ISO_DASHED;
67             }
68             elsif ($date =~ /^(\d\d\d\d)(\d\d)(\d\d)$/) {
69 6         21 $ymdref = [$1, $2, $3];
70 6         8 $format = FORMAT_ISO_NO_DASH;
71             }
72             else {
73 0         0 croak "unexpected '$key' date '$date'";
74             }
75              
76 16 50       59 if (check_date(@$ymdref)) {
77 16         38 return ($ymdref, $format);
78             }
79             else {
80 0         0 croak "invalid date for '$key' parameter";
81             }
82              
83             }
84              
85             sub next {
86 40     40 1 844 my $self = shift ;
87              
88 40         41 eval { $self->isa('Date::Calc::Iterator') } ;
  40         69  
89 40 50       64 die "next() is an object method" if $@ ;
90              
91 40 100       73 return undef if $self->{delta} > $self->{maxdelta} ;
92              
93 33         38 my @next_date = Add_Delta_Days(@{$self->{from}},$self->{delta}) ;
  33         81  
94 33         44 $self->{delta} += $self->{step} ;
95 33 100       63 if ($self->{format} == FORMAT_ARRAYREF) {
    100          
96 11 50       24 return wantarray ? @next_date : \@next_date ;
97             }
98             elsif ($self->{format} == FORMAT_ISO_DASHED) {
99 11         40 return sprintf('%d-%.2d-%.2d', @next_date);
100             }
101             else {
102 11         33 return sprintf('%d%.2d%.2d', @next_date);
103             }
104             }
105              
106             1;
107              
108             __END__