Perl楽しいから好き

Perlをはじめとしたプログラミング周りのあれこれについて。モダーンなPerlを楽しんでいます。

Perlで、とある年月を引数に与えるとその月の年月日をYYYYMMDD形式の配列リファレンスで返してくれるサブルーチンをテストから書いてみた

やりたいこと

'201808' 

↑みたいな引数を渡したら、

[
    qw(
        20180801 20180802 20180803 20180804 20180805 20180806 20180807 20180808 20180809 20180810
        20180811 20180812 20180813 20180814 20180815 20180816 20180817 20180818 20180819 20180820
        20180821 20180822 20180823 20180824 20180825 20180826 20180827 20180828 20180829 20180830
        20180831
    )
]

↑みたいな配列リファレンスを返してくれるサブルーチンが欲しい!運用中のWEBアプリの集計作業のためにどうしても欲しい!ということでTime::Pieceモジュールとかで、サクッとできるメソッドがあるかな~と探してみましたが無いっぽいので書くことに。

テスト部分

まずは、テストから。テストを書くことで安心感が得られます。さらに、今回はテストを書いたことで、東京オリンピック開催の2020年がうるう年だということに気づきました。いいことずくめ。

#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Test::More tests => 5;

BEGIN {use_ok('MyDateTimeUtility')}

# 31日ある月のテスト
my @expected_31 = qw(
    20180801 20180802 20180803 20180804 20180805 20180806 20180807 20180808 20180809 20180810
    20180811 20180812 20180813 20180814 20180815 20180816 20180817 20180818 20180819 20180820
    20180821 20180822 20180823 20180824 20180825 20180826 20180827 20180828 20180829 20180830
    20180831
);
is_deeply(MyDateTimeUtility::get_yyyymmdd_in_month(yyyymm => '201808'), \@expected_31, 'test 31 days');

# 30日ある月のテスト
my @expected_30 = qw(
    20180901 20180902 20180903 20180904 20180905 20180906 20180907 20180908 20180909 20180910
    20180911 20180912 20180913 20180914 20180915 20180916 20180917 20180918 20180919 20180920
    20180921 20180922 20180923 20180924 20180925 20180926 20180927 20180928 20180929 20180930
);
is_deeply(MyDateTimeUtility::get_yyyymmdd_in_month(yyyymm => '201809'), \@expected_30, 'test 30 days');

# 28日ある月のテスト
my @expected_28 = qw(
    20180201 20180202 20180203 20180204 20180205 20180206 20180207 20180208 20180209 20180210
    20180211 20180212 20180213 20180214 20180215 20180216 20180217 20180218 20180219 20180220
    20180221 20180222 20180223 20180224 20180225 20180226 20180227 20180228
);
is_deeply(MyDateTimeUtility::get_yyyymmdd_in_month(yyyymm => '201802'), \@expected_28, 'test 28 days');

# 29日ある月(うるう年)のテスト
my @expected_29 = qw(
    20200201 20200202 20200203 20200204 20200205 20200206 20200207 20200208 20200209 20200210
    20200211 20200212 20200213 20200214 20200215 20200216 20200217 20200218 20200219 20200220
    20200221 20200222 20200223 20200224 20200225 20200226 20200227 20200228 20200229
);
is_deeply(MyDateTimeUtility::get_yyyymmdd_in_month(yyyymm => '202002'), \@expected_29, 'test 29 days');

実処理部分

month_last_day メソッドのおかげで、月末日取得がとっても楽チン。

package MyDateTimeUtility;

use strict;
use warnings;
use Time::Piece;

sub get_yyyymmdd_in_month {
    my %argv = @_;
    my $yyyymm = $argv{yyyymm};
    my $t = Time::Piece->strptime($yyyymm, '%Y%m');
    my $last_day = $t->month_last_day;

    # 結果を格納する配列リファレンス
    my $yyyymmdd_ref = [];

    my $i = 0;
    while ($i < $last_day) {
        my $date = $i + 1;

        # 1桁の日付の場合、1=>01みたいに2桁に揃える
        $date = sprintf "%02d", $date;
        push @$yyyymmdd_ref, $yyyymm . $date;

        $i++;
    }

    return $yyyymmdd_ref;
}

1;

ディレクトリ構成

C:.
+---lib
|       MyDateTimeUtility.pm
|
\---t
        get_yyyymmdd_in_month.t

Time::Piece は、いつから標準モジュールなのか?

メッチャ便利なTime::Pieceモジュール。Perlで書くときの日時関係はこれメインで使わせてもらってます。で、いつから標準モジュールになってるのかな~?と気になったので調べてみました。こんなときはワンライナー

C: >  perl -MModule::CoreList -E "say Module::CoreList->first_release_by_date('Time::Piece');"

気になる結果は・・・

5.009005

バージョン5.9から入ってるみたいですね。意外と古くからあってビックリ。