File Coverage

lib/Date/Cutoff/JP.pm
Criterion Covered Total %
statement 56 56 100.0
branch 8 10 80.0
condition 5 5 100.0
subroutine 11 11 100.0
pod 1 2 50.0
total 81 84 96.4


line stmt bran cond sub pod time code
1             package Date::Cutoff::JP;
2 7     7   412162 use 5.008001;
  7         84  
3 7     7   35 use strict;
  7         9  
  7         206  
4 7     7   52 use warnings;
  7         25  
  7         353  
5              
6             our $VERSION = "0.05";
7              
8 7     7   42 use Carp;
  7         10  
  7         397  
9 7     7   3034 use Time::Seconds;
  7         22003  
  7         465  
10 7     7   3360 use Time::Piece;
  7         56041  
  7         30  
11             my $tp = Time::Piece->new();
12 7     7   3852 use Calendar::Japanese::Holiday;
  7         21063  
  7         440  
13 7     7   3012 use Date::DayOfWeek;
  7         10481  
  7         400  
14              
15 7     7   3487 use Moose;
  7         3201772  
  7         48  
16              
17             has cutoff => ( is => 'rw', isa => 'Int', default => 0 );
18             has payday => ( is => 'rw', isa => 'Int', default => 0 );
19             has late => ( is => 'rw', isa => 'Int', default => 1 );
20              
21             before 'cutoff' => sub {
22             my $self = shift;
23             my $value = shift;
24             return super() unless defined $value;
25             croak "unvalid cutoff was set: $value" if $value < 0 or 31 < $value;
26             return super();
27             };
28              
29             before 'payday' => sub {
30             my $self = shift;
31             my $value = shift;
32             return super() unless defined $value;
33             croak "unvalid payday was set: $value" if $value < 0 or 31 < $value;
34             croak "payday must be after cuttoff" if $value < $self->cutoff and $self->late == 0;
35             return super();
36             };
37              
38             before 'late' => sub {
39             my $self = shift;
40             my $value = shift;
41             return super() unless defined $value;
42             croak "unvalid lateness was set: $value" if $value < 0 or 2 < $value;
43             return super();
44             };
45              
46             __PACKAGE__->meta->make_immutable;
47              
48             sub isWeekend {
49 278     278 0 2458 my $self = shift;
50 278         884 my ($y, $m, $d ) = split "-", shift;
51 278         860 my $dow = dayofweek( $d, $m, $y );
52 278   100     10260 return isHoliday( $y, 0+$m, 0+$d, 1 ) || $dow == 6 || $dow == 0;
53             }
54              
55             sub calc_date {
56 72     72 1 77360 my $self = shift;
57 72 50       214 my $until = shift if @_;
58 72 50       289 my $t = $until? $tp->strptime( $until, '%Y-%m-%d' ) : localtime();
59            
60 72 100       7910 my $cutoff = $self->cutoff? $self->cutoff: $t->month_last_day();
61 72         736 my $str = $t->strftime('%Y-%m-') . sprintf( "%02d", $cutoff );
62 72         2873 my $ref_day = $t->strptime( $str, '%Y-%m-%d');
63 72         6102 my $over = 0;
64 72 100       174 if ( $ref_day->epoch() < $t->epoch() ) {
65 12         123 $over = 1;
66 12         32 $ref_day += ONE_DAY() * $ref_day->month_last_day();
67             }
68            
69 72         1859 $cutoff = $ref_day->ymd();
70 72         1222 while( $self->isWeekend($cutoff) ){
71 60         19145 my $ref_day = $t->strptime( $cutoff, '%Y-%m-%d');
72 60         5078 $ref_day += ONE_DAY();
73 60         3360 $cutoff = $ref_day->ymd();
74             }
75            
76 72   100     16292 $ref_day += ONE_DAY() * 28 * ( $self->late || 0 );
77 72         4686 $str = $ref_day->strftime('%Y-%m-%d');
78 72         2030 $ref_day = $t->strptime( $str, '%Y-%m-%d');
79              
80 72 100       6270 my $payday = $self->payday? $self->payday: $ref_day->month_last_day();
81 72         946 $str = $ref_day->strftime('%Y-%m-') . sprintf( "%02d", $payday );
82            
83 72         2667 my $date = $t->strptime( $str, '%Y-%m-%d' )->ymd();
84 72         7158 while( $self->isWeekend($date) ){
85 74         23033 my $ref_day = $t->strptime( $date, '%Y-%m-%d');
86 74         6185 $ref_day += ONE_DAY();
87 74         4133 $date = $ref_day->ymd();
88             }
89 72         19544 return ( cutoff => $cutoff, payday => $date, is_over => $over );
90             }
91              
92             1;
93             __END__
94              
95             =encoding utf-8
96              
97             =head1 NAME
98              
99             Date::CutOff::JP - Get the day cutoff and payday for in Japanese timezone
100              
101             =head1 SYNOPSIS
102              
103             use Date::CutOff::JP;
104             my $dco = Date::CutOff::JP->new({ cutoff => 0, late => 1, payday => 0 });
105             my %calculated = $dco->calc_date('2019-01-01');
106             print $calculated{'cutoff'}; # '2019-01-31'
107             print $calculated{'payday'}; # '2019-02-28'
108              
109              
110             =head1 DESCRIPTION
111              
112             Date::CutOff::JP provides how to calculate the day cutoff and the payday from Japanese calender.
113              
114             you can calculate the weekday for cutoff and paying without holiday in Japan.
115            
116             =head2 Accessor Methods
117            
118             =head3 cutoff()
119            
120             get/set the day cutoff in every months. 0 means the end of the month.
121              
122             =head3 payday()
123            
124             get/set the payday in every months. 0 means the end of the month.
125            
126             =head3 late()
127            
128             get/set the lateness. 0 means the cutoff and payday is at same month.
129              
130             The all you can set is Int of [ 0 .. 2 ] 3 or more returns error.
131            
132             =head2 Method
133              
134             =head3 calc_date($date)
135            
136             returns hash value with keys below:
137              
138             =over
139            
140            
141             =item cutoff
142              
143             The latest cutoff after $date.
144            
145             =item payday
146            
147             The latest payday after $date.
148              
149             =item is_over ( maybe bad key name )
150            
151             Is or not that the cutoff is pending until next month.
152              
153             =back
154            
155             =head1 BUGS
156              
157             =head1 SEE ALSO
158            
159             L<Calendar::Japanese::Holiday>,L<Date::DayOfWeek>
160            
161             L<日本の祝日YAML|https://github.com/holiday-jp/holiday_jp/blob/master/holidays.yml>
162            
163             =head1 LICENSE
164              
165             Copyright (C) worthmine.
166              
167             This library is free software; you can redistribute it and/or modify
168             it under the same terms as Perl itself.
169              
170             =head1 AUTHOR
171              
172             worthmine E<lt>worthmine@cpan.orgE<gt>
173            
174             =cut