File Coverage

blib/lib/Date/Cutoff/JP.pm
Criterion Covered Total %
statement 65 65 100.0
branch 8 10 80.0
condition 5 5 100.0
subroutine 14 14 100.0
pod 1 1 100.0
total 93 95 97.8


line stmt bran cond sub pod time code
1             package Date::Cutoff::JP;
2 7     7   1007437 use 5.008001;
  7         28  
3 7     7   37 use strict;
  7         39  
  7         277  
4 7     7   35 use warnings;
  7         16  
  7         781  
5              
6             our $VERSION = "0.08";
7              
8 7     7   42 use Carp;
  7         13  
  7         555  
9 7     7   3478 use Time::Seconds;
  7         24711  
  7         578  
10 7     7   4011 use Time::Piece;
  7         79441  
  7         34  
11             my $tp = Time::Piece->new();
12 7     7   4630 use Calendar::Japanese::Holiday;
  7         28593  
  7         639  
13 7     7   3331 use Date::DayOfWeek;
  7         12851  
  7         479  
14              
15 7     7   4099 use Moo;
  7         68204  
  7         32  
16 7     7   16774 use Types::Standard qw/Int/;
  7         946682  
  7         77  
17 7     7   25663 use namespace::clean;
  7         132078  
  7         52  
18              
19             has cutoff => ( is => 'rw', isa => Int, default => 0 );
20             has payday => ( is => 'rw', isa => Int, default => 0 );
21             has late => ( is => 'rw', isa => Int, default => 1 );
22              
23             around 'cutoff' => sub {
24             my $orig = shift;
25             my $self = shift;
26             return $self->$orig() unless @_;
27              
28             my $value = shift;
29             croak "unvalid cutoff was set: $value" if $value < 0 or 28 < $value;
30             my $day = $value? $value: 31;
31             croak "cuttoff must be before payday"
32             if $day >= $self->payday and $self->late == 0;
33             return $self->$orig($value);
34             };
35              
36             around 'payday' => sub {
37             my $orig = shift;
38             my $self = shift;
39             return $self->$orig() unless @_;
40            
41             my $value = shift;
42             croak "unvalid payday was set: $value" if $value < 0 or 28 < $value;
43             my $day = $value? $value: 31;
44             croak "payday must be after cuttoff"
45             if $day <= $self->cutoff and $self->late == 0;
46             return $self->$orig($value);
47             };
48              
49             around 'late' => sub {
50             my $orig = shift;
51             my $self = shift;
52             return $self->$orig() unless @_;
53             my $value = shift;
54             croak "unvalid lateness was set: $value" if $value < 0 or 2 < $value;
55             croak "payday is before cuttoff in same month"
56             if $value == 0 and $self->payday <= $self->cutoff;
57             return $self->$orig($value);
58             };
59              
60 7     7   7028 no Moo;
  7         15  
  7         69  
61              
62             sub _isWeekend {
63 278     278   2378 my $self = shift;
64 278         1090 my ($y, $m, $d ) = split "-", shift;
65 278         858 my $dow = dayofweek( $d, $m, $y );
66 278   100     10389 return isHoliday( $y, 0+$m, 0+$d, 1 ) || $dow == 6 || $dow == 0;
67             }
68              
69             sub calc_date {
70 72     72 1 1332264 my $self = shift;
71 72 50       348 my $until = shift if @_;
72 72 50       466 my $t = $until? $tp->strptime( $until, '%Y-%m-%d' ) : localtime();
73            
74 72 100       5516 my $cutoff = $self->cutoff? $self->cutoff: $t->month_last_day();
75 72         1212 my $str = $t->strftime('%Y-%m-') . sprintf( "%02d", $cutoff );
76 72         9113 my $ref_day = $t->strptime( $str, '%Y-%m-%d');
77 72         2317 my $over = 0;
78 72 100       208 if ( $ref_day->epoch() < $t->epoch() ) {
79 12         738 $over = 1;
80 12         27 $ref_day += ONE_DAY() * $ref_day->month_last_day();
81             }
82            
83 72         5158 $cutoff = $ref_day->ymd();
84 72         1225 while( $self->_isWeekend($cutoff) ){
85 60         20244 my $ref_day = $t->strptime( $cutoff, '%Y-%m-%d');
86 60         1915 $ref_day += ONE_DAY();
87 60         5751 $cutoff = $ref_day->ymd();
88             }
89            
90 72   100     18632 $ref_day += ONE_DAY() * 28 * ( $self->late || 0 );
91 72         4616 $str = $ref_day->strftime('%Y-%m-%d');
92 72         2867 $ref_day = $t->strptime( $str, '%Y-%m-%d');
93              
94 72 100       4005 my $payday = $self->payday? $self->payday: $ref_day->month_last_day();
95 72         1457 $str = $ref_day->strftime('%Y-%m-') . sprintf( "%02d", $payday );
96            
97 72         7096 my $date = $t->strptime( $str, '%Y-%m-%d' )->ymd();
98 72         3055 while( $self->_isWeekend($date) ){
99 74         22078 my $ref_day = $t->strptime( $date, '%Y-%m-%d');
100 74         2205 $ref_day += ONE_DAY();
101 74         6948 $date = $ref_day->ymd();
102             }
103 72         17651 return ( cutoff => $cutoff, payday => $date, is_over => $over );
104             }
105              
106             1;
107             __END__