File Coverage

blib/lib/Moment.pm
Criterion Covered Total %
statement 249 297 83.8
branch 72 122 59.0
condition 18 36 50.0
subroutine 40 40 100.0
pod 28 28 100.0
total 407 523 77.8


line stmt bran cond sub pod time code
1             package Moment;
2             $Moment::VERSION = '1.3.2';
3             # ABSTRACT: class that represents the moment in time
4              
5 12     12   763187 use strict;
  12         117  
  12         406  
6 12     12   65 use warnings FATAL => 'all';
  12         20  
  12         495  
7              
8 12     12   76 use Carp qw(croak);
  12         20  
  12         724  
9 12     12   6056 use Time::Local qw(timegm_nocheck);
  12         27236  
  12         792  
10 12     12   120 use Scalar::Util qw(blessed);
  12         22  
  12         43888  
11              
12              
13              
14              
15             sub new {
16 172     172 1 13969 my ($class, @params) = @_;
17              
18 172 100       413 if (@params == 0) {
19 1         162 croak "Incorrect usage. new() must get some params: dt, timestamp, iso_string or year/month/day/hour/minute/second. Stopped"
20             }
21              
22 171 50       460 if (@params % 2 != 0) {
23 0         0 croak 'Incorrect usage. new() must get hash like: `new( timestamp => 0 )`. Stopped';
24             }
25              
26 171         514 my %params = @params;
27              
28 171 50       531 if (blessed($class)) {
29 0         0 croak "Incorrect usage. You can't run new() on a variable. Stopped";
30             }
31              
32 171         298 my $self = {};
33 171         287 bless $self, $class;
34              
35 171         302 my $input_year = delete $params{year};
36 171         265 my $input_month = delete $params{month};
37 171         234 my $input_day = delete $params{day};
38 171         263 my $input_hour = delete $params{hour};
39 171         225 my $input_minute = delete $params{minute};
40 171         283 my $input_second = delete $params{second};
41              
42 171         219 my $input_iso_string = delete $params{iso_string};
43              
44 171         238 my $input_dt = delete $params{dt};
45              
46 171         214 my $input_timestamp = delete $params{timestamp};
47              
48 171 50       314 if (%params) {
49 0         0 croak "Incorrect usage. new() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
50             }
51              
52 171         237 my $way = 0;
53              
54 171 100       313 if (defined($input_iso_string)) {
55 9         30 $way++;
56              
57 9 50       86 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         40 $self->{_year} = $1;
59 9         39 $self->{_month} = $2 + 0;
60 9         27 $self->{_day} = $3 + 0;
61 9         26 $self->{_hour} = $4 + 0;
62 9         25 $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. iso_string $safe_iso_string is not in expected format 'YYYY-MM-DDThh:mm:ssZ'. Stopped";
68             }
69              
70 9         30 $self->_get_range_value_or_die( 'year', $self->{_year}, 1800, 2199 );
71 9         27 $self->_get_range_value_or_die( 'month', $self->{_month}, 1, 12 );
72 9         35 $self->_get_range_value_or_die( 'day', $self->{_day}, 1, $self->_get_last_day_in_year_month( $self->{_year}, $self->{_month}) );
73 9         31 $self->_get_range_value_or_die( 'hour', $self->{_hour}, 0, 23 );
74 9         30 $self->_get_range_value_or_die( 'minute', $self->{_minute}, 0, 59 );
75 9         21 $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         40 );
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         327 );
95              
96             }
97              
98 171 100       431 if (defined($input_timestamp)) {
99 29         53 $way++;
100              
101 29         94 $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 29         163 = gmtime($self->{_timestamp});
105              
106 29         90 $self->{_year} = $year + 1900;
107 29         59 $self->{_month} = $month + 1;
108 29         46 $self->{_day} = $day;
109 29         49 $self->{_hour} = $hour;
110 29         50 $self->{_minute} = $minute;
111 29         53 $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 29         176 );
122              
123             }
124              
125 171 50 100     906 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         127 $way++;
129              
130 93 100 66     798 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         111 croak "Must specify all params: year, month, day, hour, minute, second. Stopped";
135             }
136              
137 92         215 $self->{_year} = $self->_get_range_value_or_die( 'year', $input_year, 1800, 2199 );
138 92         195 $self->{_month} = $self->_get_range_value_or_die( 'month', $input_month, 1, 12 );
139 92         211 $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         181 $self->{_hour} = $self->_get_range_value_or_die( 'hour', $input_hour, 0, 23 );
141 92         176 $self->{_minute} = $self->_get_range_value_or_die( 'minute', $input_minute, 0, 59 );
142 92         175 $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         342 );
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         2518 );
162              
163             }
164              
165 170 100       361 if (defined($input_dt)) {
166 42         71 $way++;
167              
168 42 50       258 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         170 $self->{_year} = $1;
170 42         128 $self->{_month} = $2 + 0;
171 42         136 $self->{_day} = $3 + 0;
172 42         117 $self->{_hour} = $4 + 0;
173 42         93 $self->{_minute} = $5 + 0;
174 42         91 $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         134 $self->_get_range_value_or_die( 'year', $self->{_year}, 1800, 2199 );
182 42         112 $self->_get_range_value_or_die( 'month', $self->{_month}, 1, 12 );
183 42         137 $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         112 $self->_get_range_value_or_die( 'minute', $self->{_minute}, 0, 59 );
186 42         108 $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         201 );
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         1298 );
206              
207             }
208              
209 170 100       373 if ($way == 1) {
210             # this is the correct usage of new()
211             } else {
212 2         198 croak "Incorrect usage. new() must get one thing from the list: dt, timestamp or year/month/day/hour/minute/second. Stopped"
213             }
214              
215 168         422 $self->{_d} = substr($self->{_dt}, 0, 10);
216 168         312 $self->{_t} = substr($self->{_dt}, 11, 8);
217              
218 168         648 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 168         369 $self->{_weekday_number} = $self->_get_weekday_number($self->{_timestamp});
229 168         414 $self->{_weekday_name} = $wday2name{$self->{_weekday_number}};
230              
231 168         679 return $self;
232             }
233              
234              
235             sub now {
236 1     1 1 476 my ($class, @params) = @_;
237              
238 1 50       4 if (@params) {
239 0         0 croak 'Incorrect usage. now() shouldn\'t get any params. Stopped';
240             }
241              
242 1 50       5 if (blessed($class)) {
243 0         0 croak "Incorrect usage. You can't run now() on a variable. Stopped";
244             }
245              
246 1         4 my $self = $class->new(
247             timestamp => time(),
248             );
249              
250 1         4 return $self;
251             };
252              
253              
254             sub get_timestamp {
255 60     60 1 154 my ($self, @params) = @_;
256              
257 60 50       183 if (@params) {
258 0         0 croak 'Incorrect usage. get_timestamp() shouldn\'t get any params. Stopped';
259             }
260              
261 60         246 return $self->{_timestamp};
262             }
263              
264              
265             sub get_dt {
266 124     124 1 3139 my ($self, @params) = @_;
267              
268 124 50       326 if (@params) {
269 0         0 croak 'Incorrect usage. get_dt() shouldn\'t get any params. Stopped';
270             }
271              
272 124         446 return $self->{_dt};
273             }
274              
275              
276             sub get_iso_string {
277 37     37 1 14321 my ($self, @params) = @_;
278              
279 37 50       102 if (@params) {
280 0         0 croak 'Incorrect usage. get_iso_string() shouldn\'t get any params. Stopped';
281             }
282              
283 37         74 my $iso_string = $self->{_dt};
284 37         204 $iso_string =~ s/ /T/;
285 37         65 $iso_string .= 'Z';
286              
287 37         130 return $iso_string;
288             }
289              
290              
291             sub get_d {
292 36     36 1 76 my ($self, @params) = @_;
293              
294 36 50       98 if (@params) {
295 0         0 croak 'Incorrect usage. get_d() shouldn\'t get any params. Stopped';
296             }
297              
298 36         132 return $self->{_d};
299             }
300              
301              
302             sub get_t {
303 36     36 1 75 my ($self, @params) = @_;
304              
305 36 50       90 if (@params) {
306 0         0 croak 'Incorrect usage. get_t() shouldn\'t get any params. Stopped';
307             }
308              
309 36         131 return $self->{_t};
310             }
311              
312              
313             sub get_year {
314 159     159 1 251 my ($self, @params) = @_;
315              
316 159 50       324 if (@params) {
317 0         0 croak 'Incorrect usage. get_year() shouldn\'t get any params. Stopped';
318             }
319              
320 159         440 return $self->{_year};
321             }
322              
323              
324             sub get_month {
325 152     152 1 244 my ($self, @params) = @_;
326              
327 152 50       289 if (@params) {
328 0         0 croak 'Incorrect usage. get_month() shouldn\'t get any params. Stopped';
329             }
330              
331 152         449 return $self->{_month};
332             }
333              
334              
335             sub get_day {
336 41     41 1 98 my ($self, @params) = @_;
337              
338 41 50       95 if (@params) {
339 0         0 croak 'Incorrect usage. get_day() shouldn\'t get any params. Stopped';
340             }
341              
342 41         188 return $self->{_day};
343             }
344              
345              
346             sub get_hour {
347 36     36 1 80 my ($self, @params) = @_;
348              
349 36 50       99 if (@params) {
350 0         0 croak 'Incorrect usage. get_hour() shouldn\'t get any params. Stopped';
351             }
352              
353 36         150 return $self->{_hour};
354             }
355              
356              
357             sub get_minute {
358 36     36 1 74 my ($self, @params) = @_;
359              
360 36 50       102 if (@params) {
361 0         0 croak 'Incorrect usage. get_minute() shouldn\'t get any params. Stopped';
362             }
363              
364 36         125 return $self->{_minute};
365             }
366              
367              
368             sub get_second {
369 36     36 1 76 my ($self, @params) = @_;
370              
371 36 50       92 if (@params) {
372 0         0 croak 'Incorrect usage. get_second() shouldn\'t get any params. Stopped';
373             }
374              
375 36         130 return $self->{_second};
376             }
377              
378              
379             sub get_weekday_name {
380 57     57 1 116 my ($self, @params) = @_;
381              
382 57 50       162 if (@params) {
383 0         0 croak 'Incorrect usage. get_weekday_name() shouldn\'t get any params. Stopped';
384             }
385              
386 57         269 return $self->{_weekday_name};
387             }
388              
389              
390             sub get_weekday_number {
391 49     49 1 128 my ($self, @params) = @_;
392              
393 49 50       118 if (@params == 0) {
394 0         0 croak "Incorrect usage. get_weekday_number() must get param: first_day. Stopped";
395             }
396              
397 49 50       104 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         82 my $first_day = delete $params{first_day};
404              
405 49 50       89 if (%params) {
406 0         0 croak "Incorrect usage. get_weekday_number() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
407             }
408              
409 49         188 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       96 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       83 if ($number < 1) {
426 21         31 $number+=7;
427             }
428              
429 49         242 return $number;
430             }
431              
432              
433             sub is_monday {
434 2     2 1 9 my ($self, @params) = @_;
435              
436 2 50       14 if (@params) {
437 0         0 croak 'Incorrect usage. is_monday() shouldn\'t get any params. Stopped';
438             }
439              
440 2         8 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       5 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 8 my ($self, @params) = @_;
457              
458 2 50       6 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 8 my ($self, @params) = @_;
468              
469 2 50       6 if (@params) {
470 0         0 croak 'Incorrect usage. is_thursday() shouldn\'t get any params. Stopped';
471             }
472              
473 2         6 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       7 if (@params) {
481 0         0 croak 'Incorrect usage. is_friday() shouldn\'t get any params. Stopped';
482             }
483              
484 2         54 return $self->get_weekday_name() eq 'friday';
485             }
486              
487              
488             sub is_saturday {
489 2     2 1 8 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         6 return $self->get_weekday_name() eq 'saturday';
496             }
497              
498              
499             sub is_sunday {
500 2     2 1 8 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 14 my ($self, @params) = @_;
512              
513 7 50       14 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 22 my ($self, @params) = @_;
523              
524 7 50       15 if (@params != 1) {
525 0         0 croak "Incorrect usage. cmp() must get one parameter. Stopped"
526             }
527              
528 7         12 my $moment_2 = $params[0];
529              
530 7 50 33     63 if (blessed($moment_2) and $moment_2->isa('Moment')) {
531 7         17 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 525 my ($self, @params) = @_;
541              
542 2 50       8 if (@params == 0) {
543 0         0 croak 'Incorrect usage. plus() must get some params. Stopped';
544             }
545              
546 2 50       10 if (@params % 2 != 0) {
547 0         0 croak 'Incorrect usage. plus() must get hash like: `plus( hour => 1 )`. Stopped';
548             }
549              
550 2         5 my %params = @params;
551              
552 2         10 my $day = $self->_get_value_or_die('plus', 'day', delete($params{day}));
553 2         7 my $hour = $self->_get_value_or_die('plus', 'hour', delete($params{hour}));
554 2         4 my $minute = $self->_get_value_or_die('plus', 'minute', delete($params{minute}));
555 2         6 my $second = $self->_get_value_or_die('plus', 'second', delete($params{second}));
556              
557 2 50       6 if (%params) {
558 0         0 croak "Incorrect usage. plus() got unknown params: '" . join("', '", (sort keys %params)) . "'. Stopped";
559             }
560              
561 2         10 my $new_timestamp = $self->get_timestamp()
562             + $day * 86400
563             + $hour * 3600
564             + $minute * 60
565             + $second
566             ;
567              
568 2         9 my $new_moment = ref($self)->new( timestamp => $new_timestamp );
569              
570 2         7 return $new_moment;
571             }
572              
573              
574             sub minus {
575 2     2 1 502 my ($self, @params) = @_;
576              
577 2 50       9 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         5 my %params = @params;
586              
587 2         8 my $day = $self->_get_value_or_die('minus', 'day', delete($params{day}));
588 2         9 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         5 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 562 my ($self, @params) = @_;
611              
612 37 50       101 if (@params) {
613 0         0 croak 'Incorrect usage. get_month_start() shouldn\'t get any params. Stopped';
614             }
615              
616 37         104 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         101 return $start;
626             }
627              
628              
629             sub get_month_end {
630 37     37 1 595 my ($self, @params) = @_;
631              
632 37 50       89 if (@params) {
633 0         0 croak 'Incorrect usage. get_month_end() shouldn\'t get any params. Stopped';
634             }
635              
636 37         126 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         98 return $end;
646             }
647              
648             sub _get_weekday_number {
649 168     168   296 my ($self, $timestamp) = @_;
650              
651 168         821 my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst)
652             = gmtime($timestamp);
653              
654 168         417 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   5 my ($self, $properties) = @_;
660              
661 1         6 require Term::ANSIColor;
662              
663 1         3 return Term::ANSIColor::colored($self->get_iso_string(), 'yellow');
664             }
665              
666             sub _is_int {
667 926     926   7905 my ($self, $maybe_int) = @_;
668              
669 926         3447 return $maybe_int =~ /\A0\z|\A-?[1-9][0-9]*\z/;
670             }
671              
672             sub _get_value_or_die {
673 16     16   30 my ($self, $method_name, $key, $input_value) = @_;
674              
675 16         22 my $value = $input_value;
676              
677 16 100       31 $value = 0 if not defined $value;
678              
679 16 50       22 if (not $self->_is_int($value)) {
680 0         0 croak "Incorrect usage\. $method_name\(\) must get integer for '$key'. Stopped";
681             }
682              
683 16         82 return $value;
684             }
685              
686             sub _get_range_value_or_die {
687 887     887   1651 my ($self, $key, $input_value, $min, $max) = @_;
688              
689 887         1116 my $safe_value = 'undef';
690 887 50       1841 $safe_value = "'$input_value'" if defined $input_value;
691              
692 887 50       1412 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 887 50 33     2720 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 887         1747 return $input_value;
701             }
702              
703             sub _is_leap_year {
704 67     67   147 my ($self, $year) = @_;
705              
706 67 100       239 return '' if $year % 4;
707 35 100       82 return 1 if $year % 100;
708 32 100       60 return '' if $year % 400;
709 31         65 return 1;
710             }
711              
712             sub _get_last_day_in_year_month {
713 180     180   360 my ($self, $year, $month) = @_;
714              
715 180         928 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         257 my $last_day;
731              
732 180 100       359 if ($month == 2) {
733 60 100       112 if ($self->_is_leap_year($year)) {
734 30         49 $last_day = 29;
735             } else {
736 30         45 $last_day = 28;
737             }
738             } else {
739 120         215 $last_day = $days_in_month{$month};
740             }
741              
742 180         652 return $last_day;
743             }
744              
745              
746             1;
747              
748             __END__