File Coverage

blib/lib/DateTime/Calendar/Japanese/Era.pm
Criterion Covered Total %
statement 103 110 93.6
branch 19 26 73.0
condition 12 16 75.0
subroutine 20 22 90.9
pod 8 8 100.0
total 162 182 89.0


line stmt bran cond sub pod time code
1             # $Id: /mirror/datetime/DateTime-Calendar-Japanese-Era/trunk/lib/DateTime/Calendar/Japanese/Era.pm 69495 2008-08-24T15:54:28.230984Z lestrrat $
2             #
3             # Copyright (c) 2004-2007 Daisuke Maki <daisuke@endeworks.jp>
4             # All rights reserved.
5              
6             package DateTime::Calendar::Japanese::Era;
7 3     3   93189 use strict;
  3         5  
  3         78  
8 3     3   13 use warnings;
  3         3  
  3         84  
9 3     3   22 use base qw(Class::Accessor::Fast Class::Data::Inheritable);
  3         3  
  3         1295  
10 3     3   10355 use DateTime;
  3         922791  
  3         115  
11 3     3   19 use DateTime::Infinite;
  3         5  
  3         54  
12 3     3   1801 use Encode ();
  3         21025  
  3         73  
13 3     3   16 use Exporter qw(import);
  3         4  
  3         78  
14 3     3   1207 use File::ShareDir;
  3         11793  
  3         116  
15 3     3   1314 use Params::Validate();
  3         6132  
  3         60  
16 3     3   1129 use YAML ();
  3         14183  
  3         58  
17 3     3   15 use constant NORTH_REGIME => 1;
  3         2  
  3         132  
18 3     3   9 use constant SOUTH_REGIME => 2;
  3         3  
  3         158  
19              
20 3         19 use constant SOUTH_REGIME_START => DateTime->new(
21             year => 1331,
22             month => 11,
23             day => 7,
24             time_zone => 'Asia/Tokyo'
25 3     3   9 );
  3         5  
26 3         11 use constant SOUTH_REGIME_END => DateTime->new(
27             year => 1392,
28             month => 11,
29             day => 27,
30             time_zone => 'Asia/Tokyo'
31 3     3   27333 );
  3         3  
32             our $VERSION = '0.08003';
33             our @EXPORT_OK = qw(SOUTH_REGIME NORTH_REGIME);
34              
35             __PACKAGE__->mk_accessors($_) for qw(id name start end);
36              
37             __PACKAGE__->mk_classdata(MainDataFile =>
38             File::ShareDir::dist_file('DateTime-Calendar-Japanese-Era', 'eras.yaml')
39             );
40             __PACKAGE__->mk_classdata(SouthRegimeDataFile =>
41             File::ShareDir::dist_file('DateTime-Calendar-Japanese-Era', 'south-eras.yaml')
42             );
43              
44             my(%ERAS_BY_ID, %ERAS_BY_NAME, @ERAS_BY_CENTURY, @SOUTH_REGIME_ERAS);
45              
46             my %NewValidate = (
47             id => { type => Params::Validate::SCALAR() },
48             name => { type => Params::Validate::SCALAR() },
49             start => { isa => 'DateTime' },
50             end => { isa => 'DateTime' },
51             );
52              
53             sub new
54             {
55 745     745 1 725 my $class = shift;
56 745         11463 my %args = Params::Validate::validate(@_, \%NewValidate);
57 745         4069 $class->SUPER::new({ %args });
58             }
59              
60             sub clone
61             {
62 4     4 1 6 my $self = shift;
63 4         12 return ref($self)->new(
64             id => $self->id,
65             name => $self->name,
66             start => $self->start->clone,
67             end => $self->end->clone
68             );
69             }
70              
71             sub lookup_by_id
72             {
73 0     0 1 0 my $class = shift;
74 0         0 my %args = Params::Validate::validate(@_, {
75             id => { type => Params::Validate::SCALAR() }
76             });
77              
78             return exists $ERAS_BY_ID{ $args{id} } ?
79 0 0       0 $ERAS_BY_ID{ $args{id} }->clone : ();
80             }
81              
82             sub lookup_by_name
83             {
84 1     1 1 21 my $class = shift;
85 1         14 my %args = Params::Validate::validate(@_, {
86             name => { type => Params::Validate::SCALAR() },
87             encoding => { optional => 1 },
88             });
89             my $name = $args{encoding} ?
90 1 50       4 Encode::decode($args{encoding}, $args{name}) : $args{name};
91              
92             return exists $ERAS_BY_NAME{ $name } ?
93 1 50       6 $ERAS_BY_NAME{ $name }->clone : ();
94             }
95              
96             sub lookup_by_date
97             {
98 3     3 1 909 my $class = shift;
99 3         83 my %args = Params::Validate::validate(@_, {
100             datetime => { can => 'utc_rd_values' },
101             regime => { type => Params::Validate::SCALAR(), default => NORTH_REGIME }
102             } );
103              
104 3         19 my $dt_utc = DateTime->from_object(object => $args{datetime});
105             # $dt_utc->set_time_zone('UTC');
106              
107 3         1182 my @candidates;
108 3 100 66     17 if ($args{regime} == SOUTH_REGIME && $dt_utc >= SOUTH_REGIME_START && $dt_utc <= SOUTH_REGIME_END) {
      66        
109 1         444 @candidates = @SOUTH_REGIME_ERAS;
110             } else {
111 2         9 my $century = int($dt_utc->year() / 100);
112 2 100       18 my $r = $century >= $#ERAS_BY_CENTURY ?
113             $ERAS_BY_CENTURY[$#ERAS_BY_CENTURY] :
114             $ERAS_BY_CENTURY[$century];
115 2 50       7 if (! defined($r) ) {
116 0         0 return;
117             }
118 2         11 @candidates = @$r;
119             }
120              
121 3         5 foreach my $era (@candidates) {
122 20 100 66     5652 if ($era->start <= $dt_utc && $era->end > $dt_utc) {
123 3         1002 return $era->clone;
124             }
125             }
126 0         0 return;
127             }
128              
129             sub register_era
130             {
131 711     711 1 654 my $class = shift;
132 711         20417 my %args = Params::Validate::validate(@_, {
133             object => { isa => __PACKAGE__, optional => 1 },
134             id => { type => Params::Validate::SCALAR(), optional => 1 },
135             name => { type => Params::Validate::SCALAR(), optional => 1 },
136             start => { isa => 'DateTime', optional => 1 },
137             end => { isa => 'DateTime', optional => 1 },
138             });
139              
140 711         3306 my $era = delete $args{object};
141 711 50       1388 if (!exists $args{object}) {
142 711         1614 $era = __PACKAGE__->new(%args);
143             }
144              
145 711 50       6549 if (exists $ERAS_BY_ID{ $era->id }) {
146 0         0 Carp::croak("Era with id = " . $era->id() . " already exists!");
147             }
148 711         6074 $ERAS_BY_ID{ $era->id } = $era;
149              
150 711         4778 $ERAS_BY_NAME{ $era->name } = $era;
151              
152 711         2712 my $start_century = int($era->start->year() / 100);
153 711         4442 my $end_century = int($era->end->year() / 100);
154              
155 711   100     3586 $ERAS_BY_CENTURY[ $start_century ] ||= [];
156 711         529 push @{ $ERAS_BY_CENTURY[ $start_century ] }, $era;
  711         1054  
157              
158 711 100 66     2513 if ($start_century != $end_century && $end_century !~ /^-?inf/) {
159 42   100     154 $ERAS_BY_CENTURY[ $end_century ] ||= [];
160 42         47 push @{ $ERAS_BY_CENTURY[ $end_century ] }, $era;
  42         120  
161             }
162             }
163              
164             sub registered
165             {
166 0     0 1 0 return values (%ERAS_BY_ID);
167             }
168              
169             sub load_from_file
170             {
171 6     6 1 55 my($class, $file, $opts) = @_;
172              
173 6         6 my $ID = 0;
174 6         5 my $NAME = 1;
175 6         6 my $START = 2;
176 6         5 my $END = 3;
177 6         6 my @eras = @{ YAML::LoadFile($file) };
  6         22  
178 6         398578 foreach my $idx (0..$#eras) {
179 741         848 my $this_era = $eras[$idx];
180 741         2091 my $start_date = DateTime->new(
181             year => $this_era->[$START]->[0],
182             month => $this_era->[$START]->[1],
183             day => $this_era->[$START]->[2],
184             time_zone => 'Asia/Tokyo'
185             );
186              
187 741         235458 my $end_date;
188 741 100       1322 if ($idx == $#eras) {
189 6         81 $end_date = DateTime::Infinite::Future->new();
190             } else {
191 735         864 my $next_era = $eras[$idx + 1];
192 735 100       1008 if ($this_era->[$END]) {
193 3         15 $end_date = DateTime->new(
194             year => $this_era->[$END]->[0],
195             month => $this_era->[$END]->[1],
196             day => $this_era->[$END]->[2],
197             time_zone => 'Asia/Tokyo'
198             );
199             } else {
200 732         1777 $end_date = DateTime->new(
201             year => $next_era->[$START]->[0],
202             month => $next_era->[$START]->[1],
203             day => $next_era->[$START]->[2],
204             time_zone => 'Asia/Tokyo'
205             );
206             }
207             }
208              
209             # we create the dates in Asia/Tokyo time, but for calculation
210             # we really want them to be in UTC.
211             # $start_date->set_time_zone('UTC');
212             # $end_date->set_time_zone('UTC');
213              
214 741 100       231415 if ( $opts->{is_south_regime} ) {
215 30         86 push @SOUTH_REGIME_ERAS, __PACKAGE__->new(
216             id => $this_era->[$ID],
217             name => $this_era->[$NAME],
218             start => $start_date,
219             end => $end_date,
220             );
221             } else {
222 711         1577 __PACKAGE__->register_era(
223             id => $this_era->[$ID],
224             name => $this_era->[$NAME],
225             start => $start_date,
226             end => $end_date
227             );
228             }
229 741         1106 push @EXPORT_OK, $this_era->[$ID];
230 741         21493 constant->import( $this_era->[$ID], $this_era->[$ID]);
231             }
232             }
233              
234              
235             {
236             __PACKAGE__->load_from_file( __PACKAGE__->MainDataFile );
237             __PACKAGE__->load_from_file( __PACKAGE__->SouthRegimeDataFile, { is_south_regime => 1 });
238             }
239              
240             1;
241              
242             __DATA__
243              
244             __END__
245              
246             =encoding utf-8
247              
248             =head1 NAME
249              
250             DateTime::Calendar::Japanese::Era - DateTime Extension for Japanese Eras
251              
252             =head1 SYNOPSIS
253              
254             use DateTime::Calendar::Japanese::Era;
255             my $era = DateTime::Calendar::Japanese::Era->lookup_by_date(
256             datetime => DateTime->new(year => 1990)
257             );
258             my $era = DateTime::Calendar::Japanese::Era->lookup_by_id(
259             id => HEISEI_ERA
260             );
261             my $era = DateTime::Calendar::Japanese::Era->lookup_by_name(
262             name => "平成"
263             );
264              
265             my $era = DateTime::Calendar::Japanese::Era->new(
266             id => ...,
267             start => ...,
268             end => ...
269             );
270              
271             $era->id;
272             $era->start;
273             $era->end;
274              
275             =head1 DESCRIPTION
276              
277             Japan traditionally used an "era" system since 645 to denote the year. For
278             example, 2006 is "Heisei 18".
279              
280             The era system is loosely tied to the reign of an emperor: in modern days
281             (since the Meiji era) eras can only be renewed when a new emperor succeeds his
282             predecessor. Until then new eras were proclaimed for various reasons,
283             including the succession of the shogunate during the Tokugawa shogunate.
284              
285             =head1 NORTH AND SOUTH REGIMES
286              
287             During the 60 years between 1331 and 1392, there were two regimes in Japan
288             claiming to be the rightful successor to the imperial throne. During this
289             period of time, there were two sets of eras in use.
290              
291             This module by default uses eras from the North regime, but you can get the
292             South regime's eras if you explicitly specify it:
293              
294             use DateTime::Calendar::Japanese::Era qw(SOUTH_REGIME);
295             my $dt = DateTime->new( year => 1342 );
296             $era = DateTime::Calendar::Japanese::Era->lookup_by_date(
297             datetime => $dt,
298             regime => SOUTH_REGIME
299             );
300              
301             =head1 METHODS
302              
303             =head2 new
304              
305             =head2 id
306              
307             =head2 name
308              
309             =head2 start
310              
311             =head2 end
312              
313             =head2 clone
314              
315             =head1 FUNCTIONS
316              
317             =head2 register_era
318              
319             Registers a new era object in the lookup table.
320              
321             =head2 registered
322              
323             Returns all eras that are registered.
324              
325             =head2 lookup_by_id
326              
327             $heisei = DateTime::Calendar::Japanese::Era->lookup_by_id(
328             id => HEISEI
329             );
330              
331             Returns the era associated with the given era id. The IDs are provided by
332             DateTime::Calendar::Japanese::Era as constants.
333              
334             =head2 lookup_by_name
335              
336             $heisei = DateTime::Calendar::Japanese::Era->lookup_by_name(
337             name => '平成',
338             );
339              
340             Returns the era associated with the given era name. By default UTF-8 is
341             assumed for the name parameter. You can override this by specifying the
342             'encoding' parameter.
343              
344             =head2 lookup_by_date
345              
346             my $dt = DateTime->new(year => 1990);
347             $heisei = DateTime::Calendar::Japanese::Era->lookup_by_date(
348             datetime => $dt
349             );
350              
351             Returns the era associate with the given date.
352              
353             =head2 load_from_file
354              
355             Loads era definitions from the specified file. For internal use only
356              
357             =head1 CONSANTS
358              
359             Below are the list of era IDs that are known to this module:
360              
361             TAIKA
362             HAKUCHI
363             SHUCHOU
364             TAIHOU
365             KEIUN
366             WADOU
367             REIKI
368             YOUROU
369             JINKI
370             TENPYOU
371             TENPYOUKANPOU
372             TENPYOUSHOUHOU
373             TENPYOUJOUJI
374             TENPYOUJINGO
375             JINGOKEIUN
376             HOUKI
377             TENNOU
378             ENRYAKU
379             DAIDOU
380             KOUNIN
381             TENCHOU
382             JOUWA
383             KASHOU
384             NINJU
385             SAIKOU
386             TENNAN
387             JOUGAN
388             GANGYOU
389             NINNA
390             KANPYOU
391             SHOUTAI
392             ENGI
393             ENCHOU
394             SHOUHEI
395             TENGYOU
396             TENRYAKU
397             TENTOKU
398             OUWA
399             KOUHOU
400             ANNA
401             TENROKU
402             TENNEN
403             JOUGEN1
404             TENGEN
405             EIKAN
406             KANNA
407             EIEN
408             EISO
409             SHOURYAKU
410             CHOUTOKU
411             CHOUHOU
412             KANKOU
413             CHOUWA
414             KANNIN
415             JIAN
416             MANJU
417             CHOUGEN
418             CHOURYAKU
419             CHOUKYU
420             KANTOKU
421             EISHOU1
422             TENGI
423             KOUHEI
424             JIRYAKU
425             ENKYUU
426             JOUHOU
427             JOURYAKU
428             EIHOU
429             OUTOKU
430             KANJI
431             KAHOU
432             EICHOU
433             JOUTOKU
434             KOUWA
435             CHOUJI
436             KAJOU
437             TENNIN
438             TENNEI
439             EIKYU
440             GENNEI
441             HOUAN
442             TENJI
443             DAIJI
444             TENSHOU1
445             CHOUSHOU
446             HOUEN
447             EIJI
448             KOUJI1
449             TENNYOU
450             KYUAN
451             NINPEI
452             KYUJU
453             HOUGEN
454             HEIJI
455             EIRYAKU
456             OUHOU
457             CHOUKAN
458             EIMAN
459             NINNAN
460             KAOU
461             SHOUAN1
462             ANGEN
463             JISHOU
464             YOUWA
465             JUEI
466             GENRYAKU
467             BUNJI
468             KENKYU
469             SHOUJI
470             KENNIN
471             GENKYU
472             KENNEI
473             JOUGEN2
474             KENRYAKU
475             KENPOU
476             JOUKYU
477             JOUOU1
478             GENNIN
479             KAROKU
480             ANTEI
481             KANKI
482             JOUEI
483             TENPUKU
484             BUNRYAKU
485             KATEI
486             RYAKUNIN
487             ENNOU
488             NINJI
489             KANGEN
490             HOUJI
491             KENCHOU
492             KOUGEN
493             SHOUKA
494             SHOUGEN
495             BUNNOU
496             KOUCHOU
497             BUNNEI
498             KENJI
499             KOUAN1
500             SHOUOU
501             EININ
502             SHOUAN2
503             KENGEN
504             KAGEN
505             TOKUJI
506             ENKYOU1
507             OUCHOU
508             SHOUWA1
509             BUNPOU
510             GENNOU
511             GENKOU
512             SHOUCHU
513             KARYAKU
514             GENTOKU
515             SHOUKEI
516             RYAKUOU
517             KOUEI
518             JOUWA1
519             KANNOU
520             BUNNNA
521             ENBUN
522             KOUAN2
523             JOUJI
524             OUAN
525             EIWA
526             KOURYAKU
527             EITOKU
528             SHITOKU
529             KAKEI
530             KOUOU
531             MEITOKU
532             OUEI
533             SHOUCHOU
534             EIKYOU
535             KAKITSU
536             BUNNAN
537             HOUTOKU
538             KYOUTOKU
539             KOUSHOU
540             CHOUROKU
541             KANSHOU
542             BUNSHOU
543             OUNIN
544             BUNMEI
545             CHOUKYOU
546             ENTOKU
547             MEIOU
548             BUNKI
549             EISHOU2
550             DAIEI
551             KYOUROKU
552             TENBUN
553             KOUJI2
554             EIROKU
555             GENKI
556             TENSHOU2
557             BUNROKU
558             KEICHOU
559             GENNA
560             KANNEI
561             SHOUHOU
562             KEIAN
563             JOUOU2
564             MEIREKI
565             MANJI
566             KANBUN
567             ENPOU
568             TENNA
569             JOUKYOU
570             GENROKU
571             HOUEI
572             SHOUTOKU
573             KYOUHO
574             GENBUN
575             KANPOU
576             ENKYOU2
577             KANNEN
578             HOUREKI
579             MEIWA
580             ANNEI
581             TENMEI
582             KANSEI
583             KYOUWA
584             BUNKA
585             BUNSEI
586             TENPOU
587             KOUKA
588             KAEI
589             ANSEI
590             MANNEI
591             BUNKYU
592             GENJI
593             KEIOU
594             MEIJI
595             TAISHO
596             SHOUWA2
597             HEISEI
598              
599             These are the eras from the South regime during 1331-1392
600              
601             S_GENKOU
602             S_KENMU
603             S_EIGEN
604             S_KOUKOKU
605             S_SHOUHEI
606             S_KENTOKU
607             S_BUNCHU
608             S_TENJU
609             S_KOUWA
610             S_GENCHU
611              
612             =head1 AUTHOR
613              
614             Copyright (c) 2004-2007 Daisuke Maki E<lt>daisuke@endeworks.jpE<gt>
615              
616             =head1 LICENSE
617              
618             This program is free software; you can redistribute it and/or modify it
619             under the same terms as Perl itself.
620              
621             See http://www.perl.com/perl/misc/Artistic.html
622              
623             =cut
624