日割り計算を行うPerlプログラム

日割り計算をPerlプログラムで行う方法を解説します。ビジネスで、お金の計算をするときに、日割り計算を行うことがよくあります。金利を、日割りで計算する。家を借りたときに、借りた日から月末までの分だけ支払うなどです。

指定した日から、指定した日までの日数を求める

指定した日から、指定した日までの日数を求めてみましょう。

2019年7月16日から2019年12月31日までの日数(うるう年ではない)

2019年7月16日から2019年12月31日までの日数を求めてみましょう。この年は、うるう年ではないです。

use strict;
use warnings;

use Time::Piece;

# 2019年7月16日の日付オブジェクト
my $day1_tp = Time::Piece->strptime('2019-7-16', '%Y-%m-%d');

# 2019年12月31日の日付オブジェクト
my $day2_tp = Time::Piece->strptime('2019-12-31', '%Y-%m-%d');

# 差を求める。差の情報を保存するTime::Secondsオブジェクトが返る。
my $seconds = $day2_tp - $day1_tp;

# daysで、日付の差が求まるので、1を加えると正しい日数になる
my $days = $seconds->days + 1;

print "$days\n";

出力結果。

169

Time::Pieceは、Perlに標準で添付(Perl 5.10以降)されている日付・時刻のためのモジュールです。

strptimeメソッドを使うと、指定日と日付のフォーマットを指定して、Time::Pieceオブジェクトを作成できます。

Time::Pieceオブジェクトは、引き算を行うことができ、Time::Pieceオブジェクトの差を表すTime::Secondsオブジェクトが返ります。

daysメソッドを使うと、日付の差が求まります。日付の差に1を加えると、1年の正しい日数になります。

まずこれで、年の日数を分母にして計算する場合の、1年の日数を求めることができました。

年の日数を求める

年の日数を求めてみましょう。

年の日数を求める(うるう年ではない)

年の日数を求めてみましょう。2019年1月1日から2019年12月31日までの日数です。この年は、うるう年ではないです。

use strict;
use warnings;

use Time::Piece;

# 2019年1月1日の日付オブジェクト
my $day1_tp = Time::Piece->strptime('2019-1-1', '%Y-%m-%d');

# 2019年12月31日の日付オブジェクト
my $day2_tp = Time::Piece->strptime('2019-12-31', '%Y-%m-%d');

# 差を求める。差の情報を保存するTime::Secondsオブジェクトが返る。
my $seconds = $day2_tp - $day1_tp;

# daysで、日付の差が求まるので、1を加えると正しい日数になる
my $days = $seconds->days + 1;

print "$days\n";

出力結果。

365

年の日数が出力されました。

年の日数を求める(うるう年の場合)

うるう年の場合の年の日数を求めみましょう。この年は、うるう年です。年だけ変えて、上記と全く同じ処理を書きます。

use strict;
use warnings;

use Time::Piece;

# 2020年1月1日の日付オブジェクト
my $day1_tp = Time::Piece->strptime('2020-1-1', '%Y-%m-%d');

# 2020年12月31日の日付オブジェクト
my $day2_tp = Time::Piece->strptime('2020-12-31', '%Y-%m-%d');

# 差を求める。差の情報を保存するTime::Secondsオブジェクトが返る。
my $seconds = $day2_tp - $day1_tp;

# daysで、日付の差が求まるので、1を加えると正しい日数になる
my $days = $seconds->days + 1;

print "$days\n";

出力結果。

366

うるう年でも、正しい日数になっていますね。

月の日数を求める

日付は、始まりは必ず1日ですが、終わりの日は、31日、30日、29日、28日の場合がありますね。このような場合にプログラムで自動的に求めるには、次のようにします。

まず、次の月の最初の日を取得します。2020年2月の日数を取得してみましょう。この年は、うるう年です。

use strict;
use warnings;

use Time::Piece;

# 年
my $year = 2020;

# 月
my $mon = 2;

# 次の月
my $mon_next = $mon + 1;

# 次の月の最初の日のTime::Pieceオブジェクト
my $next_mon_tp = Time::Piece->strptime("$year-$mon_next-1", '%Y-%m-%d');

# 1秒引くと、前月の最後の日の情報が得られる
my $this_mon_last_tp = $next_mon_tp - 1;

# 最後の日を取得。これは月数と同じ値。
my $this_mon_days_count = $this_mon_last_tp->mday;

print "$this_mon_days_count\n";

出力結果。

29

うるう年の2月の日数になっていますね。

年の日数、月の日数、ある日からある日までの日数がわかればOK

年の日数、月の日数、ある日からある日までの日数がわかれば日割り計算はできますね。

日割り金額 = 金額 * (日数 / 年あるいは月の日数)

初月の家賃を求めるプログラムサンプル

初月の家賃を求めるプログラムサンプルです。月額79000円で、2020年6月18日に、引き渡した場合の、初月の家賃です。

use strict;
use warnings;

use Time::Piece;

# 家賃
my $yatin = 79_000;

# 年
my $year = 2020;

# 月
my $mon = 6;

# 開始日
my $start_mday = 18;

# 次の月
my $mon_next = $mon + 1;

# 次の月の最初の日のTime::Pieceオブジェクト
my $next_mon_tp = Time::Piece->strptime("$year-$mon_next-1", '%Y-%m-%d');

# 1秒引くと、前月の最後の日の情報が得られる
my $this_mon_last_tp = $next_mon_tp - 1;

# 最後の日を取得。これは月数と同じ値。
my $this_mon_days_count = $this_mon_last_tp->mday;

# 2020年6月19日の日付オブジェクト
my $day1_tp = Time::Piece->strptime("2020-6-$start_mday", '%Y-%m-%d');

# 2020年12月31日の日付オブジェクト
my $day2_tp = Time::Piece->strptime("2020-6-$this_mon_days_count", '%Y-%m-%d');

# 差を求める。差の情報を保存するTime::Secondsオブジェクトが返る。
my $seconds = $day2_tp - $day1_tp;

# 日数
my $days_count = $seconds->days + 1;

# 日割り家賃
my $hiwari_yatin = $yatin * ($days_count / $this_mon_days_count);

# 小数点切り捨て
my $hiwari_yatin_cut = int $hiwari_yatin;

print "$hiwari_yatin_cut\n";

出力結果。

34233

初月家賃は「34,233円」となりました。

日割り計算をした後、最後に小数点を切り捨てています。

このプログラムは、コピー&ペーストして、PerlBanjoで、すぐに試すことができます。

関連情報