File Coverage

blib/lib/Date/Japanese/Era.pm
Criterion Covered Total %
statement 83 87 95.4
branch 28 34 82.3
condition 6 9 66.6
subroutine 16 16 100.0
pod 5 5 100.0
total 138 151 91.3


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