月末日を取得する



  1. Perl




  2. 日付・時刻


 月末日を取得する関数のサンプルです。Time::Localモジュールのtimelocal関数を使って存在する日付を確かめています。

use strict;
use warnings;

print "(1)月末日を取得する。\n";
my $end_of_month_200802 = end_of_month(2008, 2);
print "2008年2月の月末日は$end_of_month_200802日です。\n";

# 月末日を求める関数。
sub end_of_month {
  my ($year, $month) = @_;
  return if !$year || !$month;

  # Time::Local::timelocal関数は1900からの経過年を引数
  # にとるので、1900を引く。    
  $year -= 1900; 

  # Time::Local::timelocal関数は 1月は0,2月は1のように0から
  # 始まる月を引数に取るので、1を引く。
  $month--;

  # 月末日の候補はこの4つ
  my @days = (31, 30, 29, 28); 
    
  # 日付の存在チェック用に使用。
  require Time::Local; 
  
  for my $day (@days) {
    eval{
      # 存在しない日を指定すると例外が起こる。
      Time::Local::timelocal(0, 0, 0, $day, $month, $year);
    };
    # 例外が起こらなければ存在する日付。
    return $day unless $@;
  }
  return;
}

(参考)eval

コード解説

月末日の候補になる日付

 月末日になるのは、28日、29日、30日、31日のどれかです。31日から順にチェックしていって存在する日付であればそれが月末日です。

my @days = (31, 30, 29, 28);
存在する日付のチェック

 「存在する日付かどうかを判定する。」で解説したように、Time::Localモジュールのtimelocal関数で日付のチェックを行います。

 31日から順に28日までチェックをしていきます。存在しない日付を指定すると例外が起こるので、例外が起こらなければそれが月末日です。

require Time::Local; 
  
for my $day (@days) {
  eval{
    # 存在しない日を指定すると例外が起こる。
    Time::Local::timelocal(0, 0, 0, $day, $month, $year);
  };
  # 例外が起こらなければ存在する日付。
  return $day unless $@;
}