【Perl】Excel 形式の和暦日付に変換する


Excel で和暦の日付は次のように表される。

書式: [年号][年].[月].[日]
例  : H22.10.26
      S64.1.7

これを Perl で扱おうと思って DateTime オブジェクトを扱うスクリプト書いた。

#!/usr/bin/perl
use utf8;
use strict;
use warnings;
use DateTime::Format::Strptime;

my $fmt = new DateTime::Format::Strptime(
    pattern => "%Y/%m/%d",
);

my $平成 = $fmt->parse_datetime( "1989/1/8" );
my $昭和 = $fmt->parse_datetime( "1926/12/25" );
my $大正 = $fmt->parse_datetime( "1912/7/30" );
my $明治 = $fmt->parse_datetime( "1868/10/23" );

sub to_jp {
    my $d = shift;
    $d or return "";
    my $y = $d >= $平成 ? "H" . ( $d->year - $平成->year + 1 ) :
        $d >= $昭和 ? "S" . ( $d->year - $昭和->year + 1 ) :
        $d >= $大正 ? "T" . ( $d->year - $大正->year + 1 ) :
        $d >= $明治 ? "M" . ( $d->year - $明治->year + 1 ) :
        $d->year;
    sprintf "%s.%d.%d", $y, $d->month, $d->day;
}

for my $i (qw! 2010/10/26 1989/1/7 !) {
    my $dt = $fmt->parse_datetime( $i );
    print to_jp( $dt ) . "\n";
}
$ perl test.pl
H22.10.26
S64.1.7

ところが CPAN を見てると、例によって先人がもっとすばらしいモジュールを書いてくれていたのだ。

DateTime::Calendar::Japanese::Era – search.cpan.org
http://search.cpan.org/~dmaki/DateTime-Calendar-Japanese-Era-0.08001/lib/DateTime/Calendar/Japanese/Era.pm

同じ例を書き表すと次のようになる。

#!/usr/bin/perl
use utf8;
use strict;
use warnings;
use DateTime::Format::Strptime;
use DateTime::Calendar::Japanese::Era;

my $fmt = new DateTime::Format::Strptime(
    pattern => "%Y/%m/%d",
);

sub to_jp {
    my $d = shift;
    $d or return "";
    # 元号オブジェクトを作成
    my $era = DateTime::Calendar::Japanese::Era
        ->lookup_by_date( datetime => $d );
    # 元号IDの最初の一文字だけを使う
    my $e = substr $era->id, 0, 1;
    # 西暦年から和暦年を求める
    my $y = $d->year - $era->start->year + 1;
    sprintf "%s%d.%d.%d", $e, $y, $d->month, $d->day;
}

for my $i (qw! 2010/10/26 1989/1/7 !) {
    my $dt = $fmt->parse_datetime( $i );
    print to_jp( $dt ) . "\n";
}

DateTime::Calendar::Japanese::Era オブジェクトは元号と和暦に関するモジュールだ。以下のようなメソッドを使って元号を扱う。

DateTime::Calendar::Japanese::Era->lookup_by_date
ひきすうに DateTime オブジェクトを指定することで、元号オブジェクトのインスタンスを返す。他に、元号 ID(後述)で探す“lookup_by_id”と、元号で探す“lookup_by_name”がある。
$era->id

次のような元号 ID を返す。

元号 ID
平成 HEISEI
昭和 SHOUWA2
大正 TAISHO
明治 MEIJI

“しょうわ”と呼ばれる元号には、“承和”、“正和”、“昭和”の 3 つがあるが、それぞれ ID は“JOUWA”、“SHOUWA”、“SHOUWA2”となる。

$era->start
元号が使われた最初の日を表す DateTime オブジェクトを返す。
$era->end
元号が使われた最後の日を表す DateTime オブジェクトを返す。

よくよく読んでみると、もっと昔の元号は勿論、南朝の元号をも扱うことが出来るようだが……なんか変だぞ?? それはまた別記事にて。

コメントを残す