File Coverage

blib/lib/Date/Pregnancy.pm
Criterion Covered Total %
statement 100 102 98.0
branch 24 28 85.7
condition 18 27 66.6
subroutine 17 17 100.0
pod 3 3 100.0
total 162 177 91.5


line stmt bran cond sub pod time code
1             package Date::Pregnancy;
2              
3 6     6   4072 use strict;
  6         9  
  6         325  
4 6     6   26 use warnings;
  6         9  
  6         181  
5 6     6   918 use DateTime;
  6         142406  
  6         148  
6 6     6   28 use Carp;
  6         8  
  6         445  
7 6     6   2811 use Clone qw(clone);
  6         17744  
  6         362  
8 6     6   35 use POSIX qw(ceil);
  6         10  
  6         56  
9 6     6   371 use vars qw($VERSION @ISA @EXPORT_OK);
  6         10  
  6         309  
10             require Exporter;
11 6     6   21 use POSIX qw(floor);
  6         8  
  6         23  
12 6     6   326 use 5.008; #5.8.0
  6         13  
13              
14             $VERSION = '0.05';
15             @ISA = qw(Exporter);
16              
17             @EXPORT_OK = qw(
18             calculate_birthday calculate_week calculate_month
19             _countback _266days _40weeks
20             );
21              
22 6     6   29 use constant AVG_CYCLE => 28;
  6         7  
  6         428  
23 6     6   27 use constant DAY => ( 60 * 60 * 24 );
  6         8  
  6         4262  
24              
25             sub _40weeks {
26 67   66 67   1793 my $dt = shift
27             || carp "first_day_of_last_period parameter is mandatory";
28 67 100       2284 return undef unless ( ref $dt );
29              
30 66         5045 my $birthday = clone($dt);
31 66         289 $birthday->add( weeks => 40 );
32              
33 66         31474 return $birthday;
34             }
35              
36             sub _266days {
37 9     9   277 my ( $dt, $period_cycle_length ) = @_;
38              
39 9 100       34 unless ( ref $dt ) {
40 1         122 carp "first_day_of_last_period parameter is mandatory";
41 1         5 return undef;
42             }
43              
44 8 100       19 if ( !$period_cycle_length ) {
45 1         90 carp "period_cycle_length parameter is mandatory";
46 1         74 return undef;
47             }
48              
49 7         1133 my $birthday = clone($dt);
50 7 100       31 if ( $period_cycle_length > 28 ) {
    50          
51 1         19 $birthday->add( seconds =>
52             ( DAY * floor( $period_cycle_length * 0.85 * ( 2 / 3 ) ) ) );
53              
54             } elsif ( $period_cycle_length < 29 ) {
55 6         57 $birthday->add( seconds => ( DAY * ( $period_cycle_length / 2 ) ) );
56             }
57 7         3101 $birthday->add( days => 266 );
58              
59 7         2622 return $birthday;
60             }
61              
62             sub _countback {
63 6   66 6   138 my $dt = shift
64             || carp "first_day_of_last_period parameter is mandatory";
65 6 100       162 return undef unless ( ref $dt );
66              
67 5         855 my $birthday = clone($dt);
68              
69 5         19 $birthday->add( days => 7 );
70 5         2031 $birthday->subtract( months => 3 );
71 5         2238 $birthday->add( years => 1 );
72              
73             #if ($dt->month < 3) {
74             #}
75              
76 5         1903 return $birthday;
77             }
78              
79             sub calculate_birthday {
80 84     84 1 6786 my %params = @_;
81              
82 84   100     192 my $method = $params{'method'} || '266days';
83              
84 84   100     178 my $period_cycle_length = $params{'period_cycle_length'} || AVG_CYCLE;
85              
86 84   66     1497 my $first_day_of_last_period = $params{'first_day_of_last_period'}
87             || carp "first_day_of_last_period parameter is mandatory";
88 84 100       2521 return undef unless ( ref $first_day_of_last_period );
89              
90 76         112 my $calculation = "_$method";
91 76         141 my @methods = qw(_countback _266days _40weeks);
92              
93 76 100       102 unless ( grep {/$method/} @methods ) {
  228         738  
94 1         147 croak "Unknown method: $params{'method'}";
95             }
96              
97 75         84 $calculation .= '($first_day_of_last_period';
98              
99 75 100       140 if ( $method eq '266days' ) {
100 6         8 $calculation .= ', $period_cycle_length';
101             }
102 75         71 $calculation .= ');';
103              
104 75         4634 my $birthday = eval("$calculation");
105 75 50       248 croak $@ if $@;
106              
107 75         211 return $birthday;
108             }
109              
110             sub calculate_week {
111 55     55 1 50854 my %params = @_;
112              
113 55   50     250 my $period_cycle_length = $params{'period_cycle_length'} || AVG_CYCLE;
114              
115 55   66     184 my $now = $params{'date'} || DateTime->now;
116 55         2571 $now->set_time_zone('UTC');
117              
118 55   50     964 my $method = $params{'method'} || '40weeks';
119              
120 55         47 my $birthday;
121 55 50       93 if ( $params{'birthday'} ) {
122 0         0 $birthday = $params{'birthday'};
123              
124             } else {
125             $birthday = calculate_birthday(
126 55         117 first_day_of_last_period => $params{'first_day_of_last_period'},
127             period_cycle_length => $period_cycle_length,
128             method => $method,
129             );
130 55 100       874 return undef unless ( ref $birthday );
131             }
132 52         146 $birthday->set_time_zone('UTC');
133              
134 52         5977 $birthday->subtract( months => 9 );
135              
136 52         25728 my $duration = $birthday->delta_days($now);
137              
138 52         3235 return ( $duration->weeks + 1 );
139             }
140              
141             sub calculate_month {
142 14     14 1 10499 my %params = @_;
143              
144 14   50     66 my $period_cycle_length = $params{'period_cycle_length'} || AVG_CYCLE;
145              
146 14   66     52 my $now = $params{'date'} || DateTime->now;
147 14         1114 $now->set_time_zone('UTC');
148              
149 14   50     302 my $method = $params{'method'} || '40weeks';
150              
151 14         12 my $birthday;
152 14 50       26 if ( $params{'birthday'} ) {
153 0         0 $birthday = $params{'birthday'};
154              
155             } else {
156             $birthday = calculate_birthday(
157 14         31 first_day_of_last_period => $params{'first_day_of_last_period'},
158             period_cycle_length => $period_cycle_length,
159             method => $method,
160             );
161 14 100       45 return undef unless ( ref $birthday );
162             }
163 11         26 $birthday->set_time_zone('UTC');
164              
165 11         1003 $birthday->subtract( months => 9 );
166              
167 11         4642 my $duration = $birthday->delta_md($now);
168              
169 11         1540 return ( $duration->months + 1 );
170             }
171              
172             1;
173              
174             __END__