File Coverage

blib/lib/Date/Japanese/Era.pm
Criterion Covered Total %
statement 82 86 95.3
branch 26 32 81.2
condition 6 9 66.6
subroutine 16 16 100.0
pod 5 5 100.0
total 135 148 91.2


line stmt bran cond sub pod time code
1             package Date::Japanese::Era;
2              
3 2     2   110690 use strict;
  2         12  
  2         70  
4             our $VERSION = '0.07';
5              
6 2     2   11 use Carp;
  2         3  
  2         118  
7 2     2   11 use constant END_OF_LUNAR => 1872;
  2         3  
  2         1974  
8              
9             our(%ERA_TABLE, %ERA_JA2ASCII, %ERA_ASCII2JA);
10              
11             sub import {
12 2     2   13 my $self = shift;
13 2 100       7 if (@_) {
14 1         1 my $table = shift;
15 1     1   49 eval qq{use Date::Japanese::Era::Table::$table};
  1         353  
  1         3  
  1         85  
16 1 50       1212 die $@ if $@;
17             }
18             else {
19 1         327 require Date::Japanese::Era::Table;
20 1         109 import Date::Japanese::Era::Table;
21             }
22             }
23              
24             sub new {
25 54     54 1 11624 my($class, @args) = @_;
26 54         167 my $self = bless {
27             name => undef,
28             year => undef,
29             gregorian_year => undef,
30             }, $class;
31              
32 54 100       173 if (@args == 3) {
    100          
    100          
33 23         57 $self->_from_ymd(@args);
34             }
35             elsif (@args == 2) {
36 24         54 $self->_from_era(@args);
37             }
38             elsif (@args == 1) {
39 6         10 $self->_dwim(@args);
40             }
41             else {
42 1         152 croak "odd number of arguments: ", scalar(@args);
43             }
44              
45 48         107 return $self;
46             }
47              
48             sub _from_ymd {
49 23     23   42 my($self, @ymd) = @_;
50              
51 23 100       52 if ($ymd[0] <= END_OF_LUNAR) {
52 1         86 Carp::carp("In $ymd[0] they didn't use gregorious date.");
53             }
54              
55 23         809 require Date::Calc;
56              
57             # XXX can be more efficient
58 23         10144 for my $era (keys %ERA_TABLE) {
59 69         98 my $data = $ERA_TABLE{$era};
60 69 100 100     80 if (Date::Calc::Delta_Days(@{$data}[1..3], @ymd) >= 0 &&
  69         209  
61 44         128 Date::Calc::Delta_Days(@ymd, @{$data}[4..6]) >= 0) {
62 21         39 $self->{name} = $era;
63 21         40 $self->{year} = $ymd[0] - $data->[1] + 1;
64 21         43 $self->{gregorian_year} = $ymd[0];
65 21         42 return;
66             }
67             }
68              
69 1         73 croak "Unsupported date: ", join('-', @ymd);
70             }
71              
72             sub _from_era {
73 30     30   47 my($self, $era, $year) = @_;
74 30 100       124 if ($era =~ /^[a-zA-Z]+$/) {
75 9         23 $era = $self->_ascii2ja($era);
76             }
77              
78 29 50       73 unless (utf8::is_utf8($era)) {
79 0         0 croak "Era needs to be Unicode string";
80             }
81              
82 29 100       158 my $data = $ERA_TABLE{$era}
83             or croak "Unknown era name: $era";
84              
85 28         53 my $g_year = $data->[1] + $year - 1;
86 28 100       54 if ($g_year > $data->[4]) {
87 1         91 croak "Invalid combination of era and year: $era-$year";
88             }
89              
90 27         37 $self->{name} = $era;
91 27         36 $self->{year} = $year;
92 27         47 $self->{gregorian_year} = $g_year;
93             }
94              
95             sub _dwim {
96 6     6   11 my($self, $str) = @_;
97              
98 6 50       13 unless (utf8::is_utf8($str)) {
99 0         0 croak "Era should be in Unicode";
100             }
101              
102 6         20 my $gengou_re = join "|", keys %ERA_JA2ASCII;
103              
104 6 50       68 $str =~ s/^($gengou_re)//
105             or croak "Can't extract Era from $str";
106              
107 6         16 my $era = $1;
108              
109 6         16 $str =~ s/\x{5E74}$//; # nen
110 6         13 my $year = _number($str);
111              
112 6 50       75332 unless (defined $year) {
113 0         0 croak "Can't parse year from $str";
114             }
115              
116 6         16 $self->_from_era($era, $year);
117             }
118              
119             sub _number {
120 6     6   9 my $str = shift;
121              
122 6         16 $str =~ s/([\x{FF10}-\x{FF19}])/;ord($1)-0xff10/eg;
  4         11  
123              
124 6 100       22 if ($str =~ /^\d+$/) {
125 4         9 return $str;
126             } else {
127 2         4 eval { require Lingua::JA::Numbers };
  2         548  
128 2 50       27616 if ($@) {
129 0         0 croak "require Lingua::JA::Numbers to read Japanized numbers";
130             }
131              
132 2         6 return Lingua::JA::Numbers::ja2num($str);
133             }
134             }
135              
136             sub _ascii2ja {
137 9     9   16 my($self, $ascii) = @_;
138 9   66     108 return $ERA_ASCII2JA{$ascii} || croak "Unknown era name: $ascii";
139             }
140              
141             sub _ja2ascii {
142 8     8   15 my($self, $ja) = @_;
143 8   33     32 return $ERA_JA2ASCII{$ja} || croak "Unknown era name: $ja";
144             }
145              
146             sub name {
147 27     27 1 2233 my $self = shift;
148 27         81 return $self->{name};
149             }
150              
151             *gengou = \&name;
152              
153             sub name_ascii {
154 8     8 1 57 my $self = shift;
155 8         18 return $self->_ja2ascii($self->name);
156             }
157              
158             sub year {
159 27     27 1 10629 my $self = shift;
160 27         82 return $self->{year};
161             }
162              
163             sub gregorian_year {
164 21     21 1 82 my $self = shift;
165 21         48 return $self->{gregorian_year};
166             }
167              
168             1;
169             __END__