File Coverage

blib/lib/Date/Pregnancy.pm
Criterion Covered Total %
statement 101 103 98.0
branch 24 28 85.7
condition 18 27 66.6
subroutine 17 17 100.0
pod 3 3 100.0
total 163 178 91.5


line stmt bran cond sub pod time code
1             package Date::Pregnancy;
2              
3 7     7   55682 use strict;
  7         18  
  7         310  
4 7     7   40 use warnings;
  7         13  
  7         233  
5 7     7   2600 use DateTime;
  7         486752  
  7         208  
6 7     7   51 use Carp;
  7         14  
  7         565  
7 7     7   7284 use Clone qw(clone);
  7         34074  
  7         580  
8 7     7   62 use POSIX qw(ceil);
  7         13  
  7         79  
9 7     7   989 use vars qw($VERSION @ISA @EXPORT_OK);
  7         13  
  7         457  
10             require Exporter;
11 7     7   36 use POSIX qw(floor);
  7         15  
  7         28  
12 7     7   431 use 5.008; #5.8.0
  7         22  
  7         487  
13              
14             $VERSION = '0.04';
15             @ISA = qw(Exporter);
16              
17             @EXPORT_OK = qw(
18             calculate_birthday calculate_week calculate_month
19             _countback _266days _40weeks
20             );
21              
22 7     7   73 use constant AVG_CYCLE => 28;
  7         45  
  7         921  
23 7     7   40 use constant DAY => ( 60 * 60 * 24 );
  7         23  
  7         8121  
24              
25             sub _40weeks {
26 67   66 67   2733 my $dt = shift
27             || carp "first_day_of_last_period parameter is mandatory";
28 67 100       3338 return undef unless ( ref $dt );
29              
30 66         3638 my $birthday = clone($dt);
31 66         366 $birthday->add( weeks => 40 );
32              
33 66         52538 return $birthday;
34             }
35              
36             sub _266days {
37 9     9   400 my ( $dt, $period_cycle_length ) = @_;
38              
39 9 100       37 unless ( ref $dt ) {
40 1         196 carp "first_day_of_last_period parameter is mandatory";
41 1         8 return undef;
42             }
43              
44 8 100       24 if ( !$period_cycle_length ) {
45 1         133 carp "period_cycle_length parameter is mandatory";
46 1         97 return undef;
47             }
48              
49 7         443 my $birthday = clone($dt);
50 7 100       46 if ( $period_cycle_length > 28 ) {
    50          
51 1         23 $birthday->add( seconds =>
52             ( DAY * floor( $period_cycle_length * 0.85 * ( 2 / 3 ) ) ) );
53              
54             } elsif ( $period_cycle_length < 29 ) {
55 6         81 $birthday->add( seconds => ( DAY * ( $period_cycle_length / 2 ) ) );
56             }
57 7         5375 $birthday->add( days => 266 );
58              
59 7         4304 return $birthday;
60             }
61              
62             sub _countback {
63 6   66 6   191 my $dt = shift
64             || carp "first_day_of_last_period parameter is mandatory";
65 6 100       251 return undef unless ( ref $dt );
66              
67 5         350 my $birthday = clone($dt);
68              
69 5         33 $birthday->add( days => 7 );
70 5         3241 $birthday->subtract( months => 3 );
71 5         3757 $birthday->add( years => 1 );
72              
73             #if ($dt->month < 3) {
74             #}
75              
76 5         2990 return $birthday;
77             }
78              
79             sub calculate_birthday {
80 84     84 1 15478 my %params = @_;
81              
82 84   100     249 my $method = $params{'method'} || '266days';
83              
84 84   100     245 my $period_cycle_length = $params{'period_cycle_length'} || AVG_CYCLE;
85              
86 84   66     1983 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       3431 return undef unless ( ref $first_day_of_last_period );
89              
90 76         204 my $calculation = "_$method";
91 76         191 my @methods = qw(_countback _266days _40weeks);
92              
93 76 100       197 unless ( grep {/$method/} @methods ) {
  228         1098  
94 1         203 croak "Unknown method: $params{'method'}";
95             }
96              
97 75         128 $calculation .= '($first_day_of_last_period';
98              
99 75 100       185 if ( $method eq '266days' ) {
100 6         11 $calculation .= ', $period_cycle_length';
101             }
102 75         108 $calculation .= ');';
103              
104 75         5930 my $birthday = eval("$calculation");
105 75 50       306 croak $@ if $@;
106              
107 75         332 return $birthday;
108             }
109              
110             sub calculate_week {
111 55     55 1 100692 my %params = @_;
112              
113 55   50     420 my $period_cycle_length = $params{'period_cycle_length'} || AVG_CYCLE;
114              
115 55   66     215 my $now = $params{'date'} || DateTime->now;
116 55         3239 $now->set_time_zone('UTC');
117              
118 55   50     1708 my $method = $params{'method'} || '40weeks';
119              
120 55         95 my $birthday;
121 55 50       131 if ( $params{'birthday'} ) {
122 0         0 $birthday = $params{'birthday'};
123              
124             } else {
125 55         161 $birthday = calculate_birthday(
126             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       180 return undef unless ( ref $birthday );
131             }
132 52         146 $birthday->set_time_zone('UTC');
133              
134 52         7550 $birthday->subtract( months => 9 );
135              
136 52         34943 my $duration = $birthday->delta_days($now);
137              
138 52         4131 return ( $duration->weeks + 1 );
139             }
140              
141             sub calculate_month {
142 14     14 1 14788 my %params = @_;
143              
144 14   50     78 my $period_cycle_length = $params{'period_cycle_length'} || AVG_CYCLE;
145              
146 14   66     98 my $now = $params{'date'} || DateTime->now;
147 14         1483 $now->set_time_zone('UTC');
148              
149 14   50     386 my $method = $params{'method'} || '40weeks';
150              
151 14         19 my $birthday;
152 14 50       31 if ( $params{'birthday'} ) {
153 0         0 $birthday = $params{'birthday'};
154              
155             } else {
156 14         38 $birthday = calculate_birthday(
157             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       58 return undef unless ( ref $birthday );
162             }
163 11         31 $birthday->set_time_zone('UTC');
164              
165 11         1633 $birthday->subtract( months => 9 );
166              
167 11         7394 my $duration = $birthday->delta_md($now);
168              
169 11         2576 return ( $duration->months + 1 );
170             }
171              
172             1;
173              
174             __END__