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.0';
3             # ABSTRACT: class that represents the moment in time
4              
5 12     12   233459 use strict;
  12         27  
  12         397  
6 12     12   122 use warnings FATAL => 'all';
  12         22  
  12         495  
7              
8 12     12   57 use Carp qw(croak);
  12         21  
  12         791  
9 12     12   9662 use Time::Local qw(timegm_nocheck);
  12         20155  
  12         746  
10 12     12   74 use Scalar::Util qw(blessed);
  12         23  
  12         48336  
11              
12              
13              
14              
15             sub new {
16 171     171 1 11932 my ($class, @params) = @_;
17              
18 171 100       431 if (@params == 0) {
19 1         149 croak "Incorrect usage. new() must get some params: dt, timestamp or year/month/day/hour/minute/secod. Stopped"
20             }
21              
22 170 50       416 if (@params % 2 != 0) {
23 0         0 croak 'Incorrect usage. new() must get hash like: `new( timestamp => 0 )`. Stopped';
24             }
25              
26 170         562 my %params = @params;
27              
28 170 50       570 if (blessed($class)) {
29 0         0 croak "Incorrect usage. You can't run new() on a variable. Stopped";
30             }
31              
32 170         263 my $self = {};
33 170         269 bless $self, $class;
34              
35 170         318 my $input_year = delete $params{year};
36 170         257 my $input_month = delete $params{month};
37 170         245 my $input_day = delete $params{day};
38 170         245 my $input_hour = delete $params{hour};
39 170         242 my $input_minute = delete $params{minute};
40 170         227 my $input_second = delete $params{second};
41              
42 170         231 my $input_iso_string = delete $params{iso_string};
43              
44 170         244 my $input_dt = delete $params{dt};
45              
46 170         244 my $input_timestamp = delete $params{timestamp};
47              
48 170 50       365 if (%params) {
49 0         0 croak "Incorrect usage. new() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
50             }
51              
52 170         239 my $way = 0;
53              
54 170 100       391 if (defined($input_iso_string)) {
55 9         12 $way++;
56              
57 9 50       55 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         33 $self->{_year} = $1;
59 9         28 $self->{_month} = $2 + 0;
60 9         23 $self->{_day} = $3 + 0;
61 9         24 $self->{_hour} = $4 + 0;
62 9         20 $self->{_minute} = $5 + 0;
63 9         22 $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. dt $safe_iso_string is not in expected format 'YYYY-MM-DDThh:mm:ssZ'. Stopped";
68             }
69              
70 9         29 $self->_get_range_value_or_die( 'year', $self->{_year}, 1800, 2199 );
71 9         28 $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         24 $self->_get_range_value_or_die( 'hour', $self->{_hour}, 0, 23 );
74 9         28 $self->_get_range_value_or_die( 'minute', $self->{_minute}, 0, 59 );
75 9         22 $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         38 );
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         262 );
95              
96             }
97              
98 170 100       381 if (defined($input_timestamp)) {
99 28         40 $way++;
100              
101 28         80 $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         148 = gmtime($self->{_timestamp});
105              
106 28         66 $self->{_year} = $year + 1900;
107 28         51 $self->{_month} = $month + 1;
108 28         42 $self->{_day} = $day;
109 28         55 $self->{_hour} = $hour;
110 28         43 $self->{_minute} = $minute;
111 28         48 $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         182 );
122              
123             }
124              
125 170 50 100     1295 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         130 $way++;
129              
130 93 100 66     1299 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         131 croak "Must specify all params: year, month, day, hour, minute, second. Stopped";
135             }
136              
137 92         243 $self->{_year} = $self->_get_range_value_or_die( 'year', $input_year, 1800, 2199 );
138 92         234 $self->{_month} = $self->_get_range_value_or_die( 'month', $input_month, 1, 12 );
139 92         253 $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         241 $self->{_hour} = $self->_get_range_value_or_die( 'hour', $input_hour, 0, 23 );
141 92         225 $self->{_minute} = $self->_get_range_value_or_die( 'minute', $input_minute, 0, 59 );
142 92         209 $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         363 );
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         2203 );
162              
163             }
164              
165 169 100       368 if (defined($input_dt)) {
166 42         54 $way++;
167              
168 42 50       224 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         158 $self->{_year} = $1;
170 42         123 $self->{_month} = $2 + 0;
171 42         101 $self->{_day} = $3 + 0;
172 42         112 $self->{_hour} = $4 + 0;
173 42         87 $self->{_minute} = $5 + 0;
174 42         94 $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         136 $self->_get_range_value_or_die( 'year', $self->{_year}, 1800, 2199 );
182 42         104 $self->_get_range_value_or_die( 'month', $self->{_month}, 1, 12 );
183 42         143 $self->_get_range_value_or_die( 'day', $self->{_day}, 1, $self->_get_last_day_in_year_month( $self->{_year}, $self->{_month}) );
184 42         113 $self->_get_range_value_or_die( 'hour', $self->{_hour}, 0, 23 );
185 42         102 $self->_get_range_value_or_die( 'minute', $self->{_minute}, 0, 59 );
186 42         102 $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         181 );
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         1111 );
206              
207             }
208              
209 169 100       355 if ($way == 1) {
210             # this is the correct usage of new()
211             } else {
212 2         243 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         447 $self->{_d} = substr($self->{_dt}, 0, 10);
216 167         342 $self->{_t} = substr($self->{_dt}, 11, 8);
217              
218 167         722 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         421 $self->{_weekday_number} = $self->_get_weekday_number($self->{_timestamp});
229 167         477 $self->{_weekday_name} = $wday2name{$self->{_weekday_number}};
230              
231 167         764 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 125 my ($self, @params) = @_;
256              
257 60 50       150 if (@params) {
258 0         0 croak 'Incorrect usage. get_timestamp() shouldn\'t get any params. Stopped';
259             }
260              
261 60         248 return $self->{_timestamp};
262             }
263              
264              
265             sub get_dt {
266 124     124 1 3130 my ($self, @params) = @_;
267              
268 124 50       293 if (@params) {
269 0         0 croak 'Incorrect usage. get_dt() shouldn\'t get any params. Stopped';
270             }
271              
272 124         617 return $self->{_dt};
273             }
274              
275              
276             sub get_iso_string {
277 37     37 1 14305 my ($self, @params) = @_;
278              
279 37 50       97 if (@params) {
280 0         0 croak 'Incorrect usage. get_iso_string() shouldn\'t get any params. Stopped';
281             }
282              
283 37         71 my $iso_string = $self->{_dt};
284 37         148 $iso_string =~ s/ /T/;
285 37         58 $iso_string .= 'Z';
286              
287 37         142 return $iso_string;
288             }
289              
290              
291             sub get_d {
292 36     36 1 79 my ($self, @params) = @_;
293              
294 36 50       115 if (@params) {
295 0         0 croak 'Incorrect usage. get_d() shouldn\'t get any params. Stopped';
296             }
297              
298 36         158 return $self->{_d};
299             }
300              
301              
302             sub get_t {
303 36     36 1 73 my ($self, @params) = @_;
304              
305 36 50       100 if (@params) {
306 0         0 croak 'Incorrect usage. get_t() shouldn\'t get any params. Stopped';
307             }
308              
309 36         165 return $self->{_t};
310             }
311              
312              
313             sub get_year {
314 159     159 1 279 my ($self, @params) = @_;
315              
316 159 50       349 if (@params) {
317 0         0 croak 'Incorrect usage. get_year() shouldn\'t get any params. Stopped';
318             }
319              
320 159         567 return $self->{_year};
321             }
322              
323              
324             sub get_month {
325 152     152 1 231 my ($self, @params) = @_;
326              
327 152 50       347 if (@params) {
328 0         0 croak 'Incorrect usage. get_month() shouldn\'t get any params. Stopped';
329             }
330              
331 152         544 return $self->{_month};
332             }
333              
334              
335             sub get_day {
336 41     41 1 79 my ($self, @params) = @_;
337              
338 41 50       100 if (@params) {
339 0         0 croak 'Incorrect usage. get_day() shouldn\'t get any params. Stopped';
340             }
341              
342 41         222 return $self->{_day};
343             }
344              
345              
346             sub get_hour {
347 36     36 1 66 my ($self, @params) = @_;
348              
349 36 50       97 if (@params) {
350 0         0 croak 'Incorrect usage. get_hour() shouldn\'t get any params. Stopped';
351             }
352              
353 36         175 return $self->{_hour};
354             }
355              
356              
357             sub get_minute {
358 36     36 1 76 my ($self, @params) = @_;
359              
360 36 50       106 if (@params) {
361 0         0 croak 'Incorrect usage. get_minute() shouldn\'t get any params. Stopped';
362             }
363              
364 36         148 return $self->{_minute};
365             }
366              
367              
368             sub get_second {
369 36     36 1 79 my ($self, @params) = @_;
370              
371 36 50       101 if (@params) {
372 0         0 croak 'Incorrect usage. get_second() shouldn\'t get any params. Stopped';
373             }
374              
375 36         150 return $self->{_second};
376             }
377              
378              
379             sub get_weekday_name {
380 57     57 1 104 my ($self, @params) = @_;
381              
382 57 50       143 if (@params) {
383 0         0 croak 'Incorrect usage. get_weekday_name() shouldn\'t get any params. Stopped';
384             }
385              
386 57         264 return $self->{_weekday_name};
387             }
388              
389              
390             sub get_weekday_number {
391 49     49 1 134 my ($self, @params) = @_;
392              
393 49 50       132 if (@params == 0) {
394 0         0 croak "Incorrect usage. get_weekday_number() must get param: first_day. Stopped";
395             }
396              
397 49 50       121 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         128 my %params = @params;
402              
403 49         79 my $first_day = delete $params{first_day};
404              
405 49 50       118 if (%params) {
406 0         0 croak "Incorrect usage. get_weekday_number() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
407             }
408              
409 49         225 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       119 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         92 my $number = $self->{_weekday_number} + $name2number{$first_day};
424              
425 49 100       107 if ($number < 1) {
426 21         30 $number+=7;
427             }
428              
429 49         311 return $number;
430             }
431              
432              
433             sub is_monday {
434 2     2 1 8 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         10 return $self->get_weekday_name() eq 'monday';
441             }
442              
443              
444             sub is_tuesday {
445 2     2 1 7 my ($self, @params) = @_;
446              
447 2 50       6 if (@params) {
448 0         0 croak 'Incorrect usage. is_tuesday() shouldn\'t get any params. Stopped';
449             }
450              
451 2         5 return $self->get_weekday_name() eq 'tuesday';
452             }
453              
454              
455             sub is_wednesday {
456 2     2 1 6 my ($self, @params) = @_;
457              
458 2 50       7 if (@params) {
459 0         0 croak 'Incorrect usage. is_wednesday() shouldn\'t get any params. Stopped';
460             }
461              
462 2         5 return $self->get_weekday_name() eq 'wednesday';
463             }
464              
465              
466             sub is_thursday {
467 2     2 1 6 my ($self, @params) = @_;
468              
469 2 50       7 if (@params) {
470 0         0 croak 'Incorrect usage. is_thursday() shouldn\'t get any params. Stopped';
471             }
472              
473 2         5 return $self->get_weekday_name() eq 'thursday';
474             }
475              
476              
477             sub is_friday {
478 2     2 1 7 my ($self, @params) = @_;
479              
480 2 50       6 if (@params) {
481 0         0 croak 'Incorrect usage. is_friday() shouldn\'t get any params. Stopped';
482             }
483              
484 2         5 return $self->get_weekday_name() eq 'friday';
485             }
486              
487              
488             sub is_saturday {
489 2     2 1 7 my ($self, @params) = @_;
490              
491 2 50       6 if (@params) {
492 0         0 croak 'Incorrect usage. is_saturday() shouldn\'t get any params. Stopped';
493             }
494              
495 2         5 return $self->get_weekday_name() eq 'saturday';
496             }
497              
498              
499             sub is_sunday {
500 2     2 1 7 my ($self, @params) = @_;
501              
502 2 50       6 if (@params) {
503 0         0 croak 'Incorrect usage. is_sunday() shouldn\'t get any params. Stopped';
504             }
505              
506 2         5 return $self->get_weekday_name() eq 'sunday';
507             }
508              
509              
510             sub is_leap_year {
511 7     7 1 10 my ($self, @params) = @_;
512              
513 7 50       17 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 16 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         9 my $moment_2 = $params[0];
529              
530 7 50 33     69 if (blessed($moment_2) and $moment_2->isa('Moment')) {
531 7         16 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 537 my ($self, @params) = @_;
541              
542 2 50       7 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         6 my %params = @params;
551              
552 2         13 my $day = $self->_get_value_or_die('plus', 'day', delete($params{day}));
553 2         8 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         16 my $second = $self->_get_value_or_die('plus', 'second', delete($params{second}));
556              
557 2 50       16 if (%params) {
558 0         0 croak "Incorrect usage. plus() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
559             }
560              
561 2         13 my $new_timestamp = $self->get_timestamp()
562             + $day * 86400
563             + $hour * 3600
564             + $minute * 60
565             + $second
566             ;
567              
568 2         8 my $new_moment = ref($self)->new( timestamp => $new_timestamp );
569              
570 2         14 return $new_moment;
571             }
572              
573              
574             sub minus {
575 2     2 1 520 my ($self, @params) = @_;
576              
577 2 50       7 if (@params == 0) {
578 0         0 croak 'Incorrect usage. minus() must get some params. Stopped';
579             }
580              
581 2 50       8 if (@params % 2 != 0) {
582 0         0 croak 'Incorrect usage. minus() must get hash like: `minus( hour => 1 )`. Stopped';
583             }
584              
585 2         7 my %params = @params;
586              
587 2         7 my $day = $self->_get_value_or_die('minus', 'day', delete($params{day}));
588 2         7 my $hour = $self->_get_value_or_die('minus', 'hour', delete($params{hour}));
589 2         6 my $minute = $self->_get_value_or_die('minus', 'minute', delete($params{minute}));
590 2         7 my $second = $self->_get_value_or_die('minus', 'second', delete($params{second}));
591              
592 2 50       8 if (%params) {
593 0         0 croak "Incorrect usage. minus() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
594             }
595              
596 2         6 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 550 my ($self, @params) = @_;
611              
612 37 50       107 if (@params) {
613 0         0 croak 'Incorrect usage. get_month_start() shouldn\'t get any params. Stopped';
614             }
615              
616 37         110 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         135 return $start;
626             }
627              
628              
629             sub get_month_end {
630 37     37 1 543 my ($self, @params) = @_;
631              
632 37 50       109 if (@params) {
633 0         0 croak 'Incorrect usage. get_month_end() shouldn\'t get any params. Stopped';
634             }
635              
636 37         122 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         125 return $end;
646             }
647              
648             sub _get_weekday_number {
649 167     167   256 my ($self, $timestamp) = @_;
650              
651 167         819 my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst)
652             = gmtime($timestamp);
653              
654 167         409 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         8 require Term::ANSIColor;
662              
663 1         9 return Term::ANSIColor::colored($self->get_iso_string(), 'yellow');
664             }
665              
666             sub _is_int {
667 925     925   7040 my ($self, $maybe_int) = @_;
668              
669 925         3648 return $maybe_int =~ /\A0\z|\A-?[1-9][0-9]*\z/;
670             }
671              
672             sub _get_value_or_die {
673 16     16   28 my ($self, $method_name, $key, $input_value) = @_;
674              
675 16         20 my $value = $input_value;
676              
677 16 100       34 $value = 0 if not defined $value;
678              
679 16 50       30 if (not $self->_is_int($value)) {
680 0         0 croak "Incorrect usage\. $method_name\(\) must get integer for '$key'. Stopped";
681             }
682              
683 16         35 return $value;
684             }
685              
686             sub _get_range_value_or_die {
687 886     886   1527 my ($self, $key, $input_value, $min, $max) = @_;
688              
689 886         1153 my $safe_value = 'undef';
690 886 50       2283 $safe_value = "'$input_value'" if defined $input_value;
691              
692 886 50       1705 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     3908 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         2008 return $input_value;
701             }
702              
703             sub _is_leap_year {
704 67     67   104 my ($self, $year) = @_;
705              
706 67 100       204 return '' if $year % 4;
707 35 100       89 return 1 if $year % 100;
708 32 100       70 return '' if $year % 400;
709 31         69 return 1;
710             }
711              
712             sub _get_last_day_in_year_month {
713 180     180   411 my ($self, $year, $month) = @_;
714              
715 180         1024 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         221 my $last_day;
731              
732 180 100       392 if ($month == 2) {
733 60 100       123 if ($self->_is_leap_year($year)) {
734 30         42 $last_day = 29;
735             } else {
736 30         42 $last_day = 28;
737             }
738             } else {
739 120         222 $last_day = $days_in_month{$month};
740             }
741              
742 180         778 return $last_day;
743             }
744              
745              
746             1;
747              
748             __END__