File Coverage

blib/lib/Moment.pm
Criterion Covered Total %
statement 244 297 82.1
branch 70 122 57.3
condition 18 36 50.0
subroutine 39 40 97.5
pod 28 28 100.0
total 399 523 76.2


line stmt bran cond sub pod time code
1             package Moment;
2             $Moment::VERSION = '1.3.1';
3             # ABSTRACT: class that represents the moment in time
4              
5 12     12   200252 use strict;
  12         35  
  12         410  
6 12     12   73 use warnings FATAL => 'all';
  12         29  
  12         566  
7              
8 12     12   75 use Carp qw(croak);
  12         33  
  12         900  
9 12     12   5683 use Time::Local qw(timegm_nocheck);
  12         26423  
  12         807  
10 12     12   101 use Scalar::Util qw(blessed);
  12         29  
  12         44228  
11              
12              
13              
14              
15             sub new {
16 171     171 1 14824 my ($class, @params) = @_;
17              
18 171 100       559 if (@params == 0) {
19 1         129 croak "Incorrect usage. new() must get some params: dt, timestamp or year/month/day/hour/minute/secod. Stopped"
20             }
21              
22 170 50       530 if (@params % 2 != 0) {
23 0         0 croak 'Incorrect usage. new() must get hash like: `new( timestamp => 0 )`. Stopped';
24             }
25              
26 170         577 my %params = @params;
27              
28 170 50       727 if (blessed($class)) {
29 0         0 croak "Incorrect usage. You can't run new() on a variable. Stopped";
30             }
31              
32 170         355 my $self = {};
33 170         341 bless $self, $class;
34              
35 170         377 my $input_year = delete $params{year};
36 170         298 my $input_month = delete $params{month};
37 170         327 my $input_day = delete $params{day};
38 170         288 my $input_hour = delete $params{hour};
39 170         285 my $input_minute = delete $params{minute};
40 170         282 my $input_second = delete $params{second};
41              
42 170         297 my $input_iso_string = delete $params{iso_string};
43              
44 170         294 my $input_dt = delete $params{dt};
45              
46 170         325 my $input_timestamp = delete $params{timestamp};
47              
48 170 50       453 if (%params) {
49 0         0 croak "Incorrect usage. new() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
50             }
51              
52 170         321 my $way = 0;
53              
54 170 100       449 if (defined($input_iso_string)) {
55 9         15 $way++;
56              
57 9 50       71 if ($input_iso_string =~ /\A([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z\z/) {
58 9         48 $self->{_year} = $1;
59 9         37 $self->{_month} = $2 + 0;
60 9         28 $self->{_day} = $3 + 0;
61 9         38 $self->{_hour} = $4 + 0;
62 9         28 $self->{_minute} = $5 + 0;
63 9         32 $self->{_second} = $6 + 0;
64             } else {
65 0         0 my $safe_iso_string = 'undef';
66 0 0       0 $safe_iso_string = "'$input_iso_string'" if defined $input_iso_string;
67 0         0 croak "Incorrect usage. iso_string $safe_iso_string is not in expected format 'YYYY-MM-DDThh:mm:ssZ'. Stopped";
68             }
69              
70 9         41 $self->_get_range_value_or_die( 'year', $self->{_year}, 1800, 2199 );
71 9         34 $self->_get_range_value_or_die( 'month', $self->{_month}, 1, 12 );
72 9         30 $self->_get_range_value_or_die( 'day', $self->{_day}, 1, $self->_get_last_day_in_year_month( $self->{_year}, $self->{_month}) );
73 9         33 $self->_get_range_value_or_die( 'hour', $self->{_hour}, 0, 23 );
74 9         59 $self->_get_range_value_or_die( 'minute', $self->{_minute}, 0, 59 );
75 9         31 $self->_get_range_value_or_die( 'second', $self->{_second}, 0, 59 );
76              
77             $self->{_timestamp} = timegm_nocheck(
78             $self->{_second},
79             $self->{_minute},
80             $self->{_hour},
81             $self->{_day},
82             $self->{_month}-1,
83             $self->{_year},
84 9         43 );
85              
86             $self->{_dt} = sprintf(
87             "%04d-%02d-%02d %02d:%02d:%02d",
88             $self->{_year},
89             $self->{_month},
90             $self->{_day},
91             $self->{_hour},
92             $self->{_minute},
93             $self->{_second},
94 9         337 );
95              
96             }
97              
98 170 100       416 if (defined($input_timestamp)) {
99 28         50 $way++;
100              
101 28         90 $self->{_timestamp} = $self->_get_range_value_or_die( 'timestamp', $input_timestamp, -5_364_662_400, 7_258_118_399 );
102              
103             my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst)
104 28         180 = gmtime($self->{_timestamp});
105              
106 28         91 $self->{_year} = $year + 1900;
107 28         66 $self->{_month} = $month + 1;
108 28         57 $self->{_day} = $day;
109 28         60 $self->{_hour} = $hour;
110 28         59 $self->{_minute} = $minute;
111 28         57 $self->{_second} = $second;
112              
113             $self->{_dt} = sprintf(
114             "%04d-%02d-%02d %02d:%02d:%02d",
115             $self->{_year},
116             $self->{_month},
117             $self->{_day},
118             $self->{_hour},
119             $self->{_minute},
120             $self->{_second},
121 28         198 );
122              
123             }
124              
125 170 50 100     1263 if (defined($input_year) or defined($input_month) or defined($input_day)
      66        
      66        
      33        
      33        
126             or defined($input_hour) or defined($input_minute) or defined($input_second)) {
127              
128 93         152 $way++;
129              
130 93 100 66     1072 if (defined($input_year) and defined($input_month) and defined($input_day)
      66        
      33        
      33        
      33        
131             and defined($input_hour) and defined($input_minute) and defined($input_second)) {
132             # ok
133             } else {
134 1         119 croak "Must specify all params: year, month, day, hour, minute, second. Stopped";
135             }
136              
137 92         271 $self->{_year} = $self->_get_range_value_or_die( 'year', $input_year, 1800, 2199 );
138 92         241 $self->{_month} = $self->_get_range_value_or_die( 'month', $input_month, 1, 12 );
139 92         279 $self->{_day} = $self->_get_range_value_or_die( 'day', $input_day, 1, $self->_get_last_day_in_year_month( $self->{_year}, $self->{_month}) );
140 92         221 $self->{_hour} = $self->_get_range_value_or_die( 'hour', $input_hour, 0, 23 );
141 92         251 $self->{_minute} = $self->_get_range_value_or_die( 'minute', $input_minute, 0, 59 );
142 92         203 $self->{_second} = $self->_get_range_value_or_die( 'second', $input_second, 0, 59 );
143              
144             $self->{_timestamp} = timegm_nocheck(
145             $self->{_second},
146             $self->{_minute},
147             $self->{_hour},
148             $self->{_day},
149             $self->{_month}-1,
150             $self->{_year},
151 92         401 );
152              
153             $self->{_dt} = sprintf(
154             "%04d-%02d-%02d %02d:%02d:%02d",
155             $self->{_year},
156             $self->{_month},
157             $self->{_day},
158             $self->{_hour},
159             $self->{_minute},
160             $self->{_second},
161 92         2598 );
162              
163             }
164              
165 169 100       466 if (defined($input_dt)) {
166 42         77 $way++;
167              
168 42 50       295 if ($input_dt =~ /\A([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})\z/) {
169 42         209 $self->{_year} = $1;
170 42         151 $self->{_month} = $2 + 0;
171 42         121 $self->{_day} = $3 + 0;
172 42         108 $self->{_hour} = $4 + 0;
173 42         126 $self->{_minute} = $5 + 0;
174 42         134 $self->{_second} = $6 + 0;
175             } else {
176 0         0 my $safe_dt = 'undef';
177 0 0       0 $safe_dt = "'$input_dt'" if defined $input_dt;
178 0         0 croak "Incorrect usage. dt $safe_dt is not in expected format 'YYYY-MM-DD hh:mm:ss'. Stopped";
179             }
180              
181 42         176 $self->_get_range_value_or_die( 'year', $self->{_year}, 1800, 2199 );
182 42         134 $self->_get_range_value_or_die( 'month', $self->{_month}, 1, 12 );
183 42         159 $self->_get_range_value_or_die( 'day', $self->{_day}, 1, $self->_get_last_day_in_year_month( $self->{_year}, $self->{_month}) );
184 42         134 $self->_get_range_value_or_die( 'hour', $self->{_hour}, 0, 23 );
185 42         130 $self->_get_range_value_or_die( 'minute', $self->{_minute}, 0, 59 );
186 42         130 $self->_get_range_value_or_die( 'second', $self->{_second}, 0, 59 );
187              
188             $self->{_timestamp} = timegm_nocheck(
189             $self->{_second},
190             $self->{_minute},
191             $self->{_hour},
192             $self->{_day},
193             $self->{_month}-1,
194             $self->{_year},
195 42         190 );
196              
197             $self->{_dt} = sprintf(
198             "%04d-%02d-%02d %02d:%02d:%02d",
199             $self->{_year},
200             $self->{_month},
201             $self->{_day},
202             $self->{_hour},
203             $self->{_minute},
204             $self->{_second},
205 42         1435 );
206              
207             }
208              
209 169 100       426 if ($way == 1) {
210             # this is the correct usage of new()
211             } else {
212 2         178 croak "Incorrect usage. new() must get one thing from the list: dt, timestamp or year/month/day/hour/minute/second. Stopped"
213             }
214              
215 167         475 $self->{_d} = substr($self->{_dt}, 0, 10);
216 167         365 $self->{_t} = substr($self->{_dt}, 11, 8);
217              
218 167         796 my %wday2name = (
219             0 => 'sunday',
220             1 => 'monday',
221             2 => 'tuesday',
222             3 => 'wednesday',
223             4 => 'thursday',
224             5 => 'friday',
225             6 => 'saturday',
226             );
227              
228 167         460 $self->{_weekday_number} = $self->_get_weekday_number($self->{_timestamp});
229 167         476 $self->{_weekday_name} = $wday2name{$self->{_weekday_number}};
230              
231 167         703 return $self;
232             }
233              
234              
235             sub now {
236 0     0 1 0 my ($class, @params) = @_;
237              
238 0 0       0 if (@params) {
239 0         0 croak 'Incorrect usage. now() shouldn\'t get any params. Stopped';
240             }
241              
242 0 0       0 if (blessed($class)) {
243 0         0 croak "Incorrect usage. You can't run now() on a variable. Stopped";
244             }
245              
246 0         0 my $self = Moment->new(
247             timestamp => time(),
248             );
249              
250 0         0 return $self;
251             };
252              
253              
254             sub get_timestamp {
255 60     60 1 192 my ($self, @params) = @_;
256              
257 60 50       174 if (@params) {
258 0         0 croak 'Incorrect usage. get_timestamp() shouldn\'t get any params. Stopped';
259             }
260              
261 60         279 return $self->{_timestamp};
262             }
263              
264              
265             sub get_dt {
266 124     124 1 2396 my ($self, @params) = @_;
267              
268 124 50       337 if (@params) {
269 0         0 croak 'Incorrect usage. get_dt() shouldn\'t get any params. Stopped';
270             }
271              
272 124         552 return $self->{_dt};
273             }
274              
275              
276             sub get_iso_string {
277 37     37 1 15436 my ($self, @params) = @_;
278              
279 37 50       124 if (@params) {
280 0         0 croak 'Incorrect usage. get_iso_string() shouldn\'t get any params. Stopped';
281             }
282              
283 37         89 my $iso_string = $self->{_dt};
284 37         183 $iso_string =~ s/ /T/;
285 37         91 $iso_string .= 'Z';
286              
287 37         151 return $iso_string;
288             }
289              
290              
291             sub get_d {
292 36     36 1 118 my ($self, @params) = @_;
293              
294 36 50       124 if (@params) {
295 0         0 croak 'Incorrect usage. get_d() shouldn\'t get any params. Stopped';
296             }
297              
298 36         156 return $self->{_d};
299             }
300              
301              
302             sub get_t {
303 36     36 1 114 my ($self, @params) = @_;
304              
305 36 50       122 if (@params) {
306 0         0 croak 'Incorrect usage. get_t() shouldn\'t get any params. Stopped';
307             }
308              
309 36         159 return $self->{_t};
310             }
311              
312              
313             sub get_year {
314 159     159 1 328 my ($self, @params) = @_;
315              
316 159 50       387 if (@params) {
317 0         0 croak 'Incorrect usage. get_year() shouldn\'t get any params. Stopped';
318             }
319              
320 159         534 return $self->{_year};
321             }
322              
323              
324             sub get_month {
325 152     152 1 305 my ($self, @params) = @_;
326              
327 152 50       364 if (@params) {
328 0         0 croak 'Incorrect usage. get_month() shouldn\'t get any params. Stopped';
329             }
330              
331 152         507 return $self->{_month};
332             }
333              
334              
335             sub get_day {
336 41     41 1 122 my ($self, @params) = @_;
337              
338 41 50       132 if (@params) {
339 0         0 croak 'Incorrect usage. get_day() shouldn\'t get any params. Stopped';
340             }
341              
342 41         191 return $self->{_day};
343             }
344              
345              
346             sub get_hour {
347 36     36 1 117 my ($self, @params) = @_;
348              
349 36 50       126 if (@params) {
350 0         0 croak 'Incorrect usage. get_hour() shouldn\'t get any params. Stopped';
351             }
352              
353 36         155 return $self->{_hour};
354             }
355              
356              
357             sub get_minute {
358 36     36 1 116 my ($self, @params) = @_;
359              
360 36 50       118 if (@params) {
361 0         0 croak 'Incorrect usage. get_minute() shouldn\'t get any params. Stopped';
362             }
363              
364 36         153 return $self->{_minute};
365             }
366              
367              
368             sub get_second {
369 36     36 1 118 my ($self, @params) = @_;
370              
371 36 50       128 if (@params) {
372 0         0 croak 'Incorrect usage. get_second() shouldn\'t get any params. Stopped';
373             }
374              
375 36         151 return $self->{_second};
376             }
377              
378              
379             sub get_weekday_name {
380 57     57 1 164 my ($self, @params) = @_;
381              
382 57 50       186 if (@params) {
383 0         0 croak 'Incorrect usage. get_weekday_name() shouldn\'t get any params. Stopped';
384             }
385              
386 57         299 return $self->{_weekday_name};
387             }
388              
389              
390             sub get_weekday_number {
391 49     49 1 136 my ($self, @params) = @_;
392              
393 49 50       117 if (@params == 0) {
394 0         0 croak "Incorrect usage. get_weekday_number() must get param: first_day. Stopped";
395             }
396              
397 49 50       125 if (@params % 2 != 0) {
398 0         0 croak "Incorrect usage. get_weekday_number() must get hash like: `get_weekday_number( first_day => 'monday' )`. Stopped";
399             }
400              
401 49         105 my %params = @params;
402              
403 49         81 my $first_day = delete $params{first_day};
404              
405 49 50       101 if (%params) {
406 0         0 croak "Incorrect usage. get_weekday_number() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
407             }
408              
409 49         155 my %name2number = (
410             sunday => 1,
411             monday => 0,
412             tuesday => -1,
413             wednesday => -2,
414             thursday => -3,
415             friday => -4,
416             saturday => -5,
417             );
418              
419 49 50       109 if (not exists $name2number{$first_day}) {
420 0         0 croak "Incorrect usage. get_weekday_number() got unknown value '$first_day' for first_day. Stopped";
421             }
422              
423 49         87 my $number = $self->{_weekday_number} + $name2number{$first_day};
424              
425 49 100       98 if ($number < 1) {
426 21         30 $number+=7;
427             }
428              
429 49         221 return $number;
430             }
431              
432              
433             sub is_monday {
434 2     2 1 10 my ($self, @params) = @_;
435              
436 2 50       5 if (@params) {
437 0         0 croak 'Incorrect usage. is_monday() shouldn\'t get any params. Stopped';
438             }
439              
440 2         9 return $self->get_weekday_name() eq 'monday';
441             }
442              
443              
444             sub is_tuesday {
445 2     2 1 13 my ($self, @params) = @_;
446              
447 2 50       9 if (@params) {
448 0         0 croak 'Incorrect usage. is_tuesday() shouldn\'t get any params. Stopped';
449             }
450              
451 2         7 return $self->get_weekday_name() eq 'tuesday';
452             }
453              
454              
455             sub is_wednesday {
456 2     2 1 12 my ($self, @params) = @_;
457              
458 2 50       9 if (@params) {
459 0         0 croak 'Incorrect usage. is_wednesday() shouldn\'t get any params. Stopped';
460             }
461              
462 2         8 return $self->get_weekday_name() eq 'wednesday';
463             }
464              
465              
466             sub is_thursday {
467 2     2 1 10 my ($self, @params) = @_;
468              
469 2 50       8 if (@params) {
470 0         0 croak 'Incorrect usage. is_thursday() shouldn\'t get any params. Stopped';
471             }
472              
473 2         8 return $self->get_weekday_name() eq 'thursday';
474             }
475              
476              
477             sub is_friday {
478 2     2 1 8 my ($self, @params) = @_;
479              
480 2 50       11 if (@params) {
481 0         0 croak 'Incorrect usage. is_friday() shouldn\'t get any params. Stopped';
482             }
483              
484 2         7 return $self->get_weekday_name() eq 'friday';
485             }
486              
487              
488             sub is_saturday {
489 2     2 1 10 my ($self, @params) = @_;
490              
491 2 50       8 if (@params) {
492 0         0 croak 'Incorrect usage. is_saturday() shouldn\'t get any params. Stopped';
493             }
494              
495 2         6 return $self->get_weekday_name() eq 'saturday';
496             }
497              
498              
499             sub is_sunday {
500 2     2 1 10 my ($self, @params) = @_;
501              
502 2 50       7 if (@params) {
503 0         0 croak 'Incorrect usage. is_sunday() shouldn\'t get any params. Stopped';
504             }
505              
506 2         7 return $self->get_weekday_name() eq 'sunday';
507             }
508              
509              
510             sub is_leap_year {
511 7     7 1 16 my ($self, @params) = @_;
512              
513 7 50       18 if (@params) {
514 0         0 croak 'Incorrect usage. is_leap_year() shouldn\'t get any params. Stopped';
515             }
516              
517 7         17 return $self->_is_leap_year( $self->get_year() );
518             }
519              
520              
521             sub cmp {
522 7     7 1 18 my ($self, @params) = @_;
523              
524 7 50       18 if (@params != 1) {
525 0         0 croak "Incorrect usage. cmp() must get one parameter. Stopped"
526             }
527              
528 7         10 my $moment_2 = $params[0];
529              
530 7 50 33     63 if (blessed($moment_2) and $moment_2->isa('Moment')) {
531 7         20 return $self->get_timestamp() <=> $moment_2->get_timestamp();
532             } else {
533 0         0 croak "Incorrect usage. cmp() must get Moment object as a parameter. Stopped";
534             }
535              
536             }
537              
538              
539             sub plus {
540 2     2 1 382 my ($self, @params) = @_;
541              
542 2 50       10 if (@params == 0) {
543 0         0 croak 'Incorrect usage. plus() must get some params. Stopped';
544             }
545              
546 2 50       12 if (@params % 2 != 0) {
547 0         0 croak 'Incorrect usage. plus() must get hash like: `plus( hour => 1 )`. Stopped';
548             }
549              
550 2         9 my %params = @params;
551              
552 2         12 my $day = $self->_get_value_or_die('plus', 'day', delete($params{day}));
553 2         9 my $hour = $self->_get_value_or_die('plus', 'hour', delete($params{hour}));
554 2         8 my $minute = $self->_get_value_or_die('plus', 'minute', delete($params{minute}));
555 2         8 my $second = $self->_get_value_or_die('plus', 'second', delete($params{second}));
556              
557 2 50       8 if (%params) {
558 0         0 croak "Incorrect usage. plus() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
559             }
560              
561 2         49 my $new_timestamp = $self->get_timestamp()
562             + $day * 86400
563             + $hour * 3600
564             + $minute * 60
565             + $second
566             ;
567              
568 2         10 my $new_moment = ref($self)->new( timestamp => $new_timestamp );
569              
570 2         9 return $new_moment;
571             }
572              
573              
574             sub minus {
575 2     2 1 398 my ($self, @params) = @_;
576              
577 2 50       10 if (@params == 0) {
578 0         0 croak 'Incorrect usage. minus() must get some params. Stopped';
579             }
580              
581 2 50       9 if (@params % 2 != 0) {
582 0         0 croak 'Incorrect usage. minus() must get hash like: `minus( hour => 1 )`. Stopped';
583             }
584              
585 2         8 my %params = @params;
586              
587 2         9 my $day = $self->_get_value_or_die('minus', 'day', delete($params{day}));
588 2         8 my $hour = $self->_get_value_or_die('minus', 'hour', delete($params{hour}));
589 2         7 my $minute = $self->_get_value_or_die('minus', 'minute', delete($params{minute}));
590 2         8 my $second = $self->_get_value_or_die('minus', 'second', delete($params{second}));
591              
592 2 50       9 if (%params) {
593 0         0 croak "Incorrect usage. minus() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
594             }
595              
596 2         7 my $new_timestamp = $self->get_timestamp()
597             - $day * 86400
598             - $hour * 3600
599             - $minute * 60
600             - $second
601             ;
602              
603 2         8 my $new_moment = ref($self)->new( timestamp => $new_timestamp );
604              
605 2         8 return $new_moment;
606             }
607              
608              
609             sub get_month_start {
610 37     37 1 465 my ($self, @params) = @_;
611              
612 37 50       124 if (@params) {
613 0         0 croak 'Incorrect usage. get_month_start() shouldn\'t get any params. Stopped';
614             }
615              
616 37         127 my $start = ref($self)->new(
617             year => $self->get_year(),
618             month => $self->get_month(),
619             day => 1,
620             hour => 0,
621             minute => 0,
622             second => 0,
623             );
624              
625 37         125 return $start;
626             }
627              
628              
629             sub get_month_end {
630 37     37 1 516 my ($self, @params) = @_;
631              
632 37 50       125 if (@params) {
633 0         0 croak 'Incorrect usage. get_month_end() shouldn\'t get any params. Stopped';
634             }
635              
636 37         120 my $end = ref($self)->new(
637             year => $self->get_year(),
638             month => $self->get_month(),
639             day => $self->_get_last_day_in_year_month( $self->get_year(), $self->get_month() ),
640             hour => 23,
641             minute => 59,
642             second => 59,
643             );
644              
645 37         116 return $end;
646             }
647              
648             sub _get_weekday_number {
649 167     167   333 my ($self, $timestamp) = @_;
650              
651 167         886 my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst)
652             = gmtime($timestamp);
653              
654 167         472 return $wday;
655             }
656              
657             # https://metacpan.org/pod/Data::Printer#MAKING-YOUR-CLASSES-DDP-AWARE-WITHOUT-ADDING-ANY-DEPS
658             sub _data_printer {
659 1     1   6 my ($self, $properties) = @_;
660              
661 1         11 require Term::ANSIColor;
662              
663 1         7 return Term::ANSIColor::colored($self->get_iso_string(), 'yellow');
664             }
665              
666             sub _is_int {
667 925     925   9412 my ($self, $maybe_int) = @_;
668              
669 925         3766 return $maybe_int =~ /\A0\z|\A-?[1-9][0-9]*\z/;
670             }
671              
672             sub _get_value_or_die {
673 16     16   41 my ($self, $method_name, $key, $input_value) = @_;
674              
675 16         26 my $value = $input_value;
676              
677 16 100       44 $value = 0 if not defined $value;
678              
679 16 50       36 if (not $self->_is_int($value)) {
680 0         0 croak "Incorrect usage\. $method_name\(\) must get integer for '$key'. Stopped";
681             }
682              
683 16         37 return $value;
684             }
685              
686             sub _get_range_value_or_die {
687 886     886   1801 my ($self, $key, $input_value, $min, $max) = @_;
688              
689 886         1372 my $safe_value = 'undef';
690 886 50       2535 $safe_value = "'$input_value'" if defined $input_value;
691              
692 886 50       1751 if (not $self->_is_int($input_value)) {
693 0         0 croak "Incorrect usage\. The $key $safe_value is not an integer number. Stopped";
694             };
695              
696 886 50 33     3751 if ( ($input_value < $min) or ($input_value > $max) ) {
697 0         0 croak "Incorrect usage. The $key $safe_value is not in range [$min, $max]. Stopped";
698             }
699              
700 886         2006 return $input_value;
701             }
702              
703             sub _is_leap_year {
704 67     67   146 my ($self, $year) = @_;
705              
706 67 100       233 return '' if $year % 4;
707 35 100       100 return 1 if $year % 100;
708 32 100       77 return '' if $year % 400;
709 31         82 return 1;
710             }
711              
712             sub _get_last_day_in_year_month {
713 180     180   459 my ($self, $year, $month) = @_;
714              
715 180         1048 my %days_in_month = (
716             1 => 31,
717             # no february
718             3 => 31,
719             4 => 30,
720             5 => 31,
721             6 => 30,
722             7 => 31,
723             8 => 31,
724             9 => 30,
725             10 => 31,
726             11 => 30,
727             12 => 31,
728             );
729              
730 180         301 my $last_day;
731              
732 180 100       429 if ($month == 2) {
733 60 100       178 if ($self->_is_leap_year($year)) {
734 30         51 $last_day = 29;
735             } else {
736 30         53 $last_day = 28;
737             }
738             } else {
739 120         228 $last_day = $days_in_month{$month};
740             }
741              
742 180         706 return $last_day;
743             }
744              
745              
746             1;
747              
748             __END__