Time::Pieceでcalコマンドっぽいものを実装する

ぽいものっていうのは、
日曜始まりじゃなくて月曜始まりって意味なんだけど、
今思うと、なんで月曜始まりにこだわったのか分かんない。。。

use v5.14;
use strict;
use warnings;
use utf8;

use Time::Piece;

sub usage {
    say "Usage:
    perl $0 Month(1-12) Year(1900-)
    ex.) perl $0 9 2014";
    exit( 0 );
}

if ( scalar(@ARGV) != 2 ) {
    usage();
}

my ( $month, $year ) = @ARGV;

if ( $year < 1900 ) {
    say "Year is invalid. ---> Year: $year";
    usage();
}

if ( $month < 1 or 12 < $month ) {
    say "Month is invalid. ---> Month: $month";
    usage();
}

my $t = Time::Piece->strptime( "$year-$month-1", '%Y-%m-%d' );
my $n = $t->month_last_day();

my $week = $t->day_of_week(); # Sunday: 0
my $offset = ( $week == 0 ) ? 6 : ($week - 1);

binmode( STDOUT, ':utf8' );

printf( "     %2d月 %d\n", $month, $year );
print "月 火 水 木 金 土 日\n";

my $i = 0;
for (; $i<$offset; $i++) {
    printf( "%2s", '' );
    print " ";
}

foreach my $day ( 1..$n ) {
    printf( "%2d", $day );

    $i++;
    if ( 7 <= $i and $day != $n ) {
        print "\n";
        $i = 0;
    }
    else {
        print " ";
    }
}

print "\n";

実行するとこんな感じ。

$ perl aaa.pl 9 2014
9月 2014
月 火 水 木 金 土 日
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

きっと、こういうことするモジュールあるんだろうなぁ・・・。

おしまい。

Leave a Comment