スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2つの日付間の差分の日数を計算するPerlプログラムの例

2つの日付間の差分の日数を計算する Perl プログラムの例。

&date_subtract(終了日, 開始日) で、開始日から終了日までの日数を返す。終了日のほうが開始日よりも過去の場合にはマイナスの値を返す。

Date::Calc モジュールによる例

use strict;
use warnings;
use Date::Calc qw(Today Delta_Days);
use Carp qw(croak);

print &date_subtract(2011, 9, 2, 2010, 6, 8)."\n";  #=> 452
print &date_subtract(2010, 6, 8, 2011, 9, 2)."\n";  #=> -452
print &date_subtract(2013, 9, 2)."\n";  #=> 指定日までの日数(正)
print &date_subtract(2011, 9, 2)."\n";  #=> 指定日からの日数(負)

sub date_subtract {

  # 開始日
  my ($year2, $month2, $date2);
  if (@_ == 6) {
    ($year2, $month2, $date2) = @_[3..5];
  }
  elsif (@_ == 3) {
    ($year2, $month2, $date2) = Today();
  }
  else {
    croak "引数が不正です";
  }

  # 終了日
  my ($year1, $month1, $date1) = @_[0..2];

  # 開始日から終了日までの日数差(終了日含まず)
  my $delta_days = Delta_Days(
      $year2, $month2, $date2,  # from
      $year1, $month1, $date1   # to
  );

  # 符号
  my $sign = $delta_days < 0 ? -1 : 1;

  # 終了日もカウントする
  return $sign * (abs($delta_days) + 1);
}

DateTime モジュールによる例

use strict;
use warnings;
use DateTime;
use DateTime::TimeZone;
use Carp qw(croak);

print &date_subtract(2011, 9, 2, 2010, 6, 8)."\n";  #=> 452
print &date_subtract(2010, 6, 8, 2011, 9, 2)."\n";  #=> -452
print &date_subtract(2013, 9, 2)."\n";  #=> 指定日までの日数(正)
print &date_subtract(2011, 9, 2)."\n";  #=> 指定日からの日数(負)

sub date_subtract {

  # タイムゾーン
  my $tz = DateTime::TimeZone->new( name => 'local' );

  # 開始日
  my $dt2;
  if (@_ == 6) {
    $dt2 = DateTime->new (
      year  => $_[3],
      month => $_[4],
      day   => $_[5],
      time_zone => $tz
    );
  }
  elsif (@_ == 3) {
    $dt2 = DateTime->now( time_zone => $tz );
  }
  else {
    croak "引数が不正です";
  }

  # 終了日
  my $dt1 = DateTime->new (
    year  => $_[0],
    month => $_[1],
    day   => $_[2],
    time_zone => $tz
  );

  # 開始日から終了日までの日数差(終了日含まず)
  # DateTime::Durationオブジェクトが作成される
  my $dur = $dt1->delta_days($dt2);

  # 符号
  my $sign = DateTime->compare($dt1, $dt2) < 0 ? -1 : 1;

  # 終了日もカウントする
  return $sign * ($dur->in_units('days') + 1);
}

Time::Local モジュールによる例

use strict;
use warnings;
use Time::Local qw(timelocal);
use Carp qw(croak);

print &date_subtract(2011, 9, 2, 2010, 6, 8)."\n";  #=> 452
print &date_subtract(2010, 6, 8, 2011, 9, 2)."\n";  #=> -452
print &date_subtract(2013, 9, 2)."\n";  #=> 指定日までの日数(正)
print &date_subtract(2011, 9, 2)."\n";  #=> 指定日からの日数(負)

sub date_subtract {

  # 1 [day] = 24 * 60 * 60 [sec]
  my $SECS_PER_DAY = 24 * 60 * 60;

  # 開始日
  my $epoch2;
  if (@_ == 6) {
    $epoch2 = timelocal(
      0, 0, 0, $_[5], $_[4]-1, $_[3]);
  }
  elsif (@_ == 3) {
    my ($day, $month, $year) = (localtime(time))[3..5];
    $epoch2 = timelocal(
      0, 0, 0, $day, $month, $year);
  }
  else {
    croak "引数が不正です";
  }

  # 終了日
  my $epoch1 = timelocal(
    0, 0, 0, $_[2], $_[1]-1, $_[0]);

  # 開始日から終了日までの日数差(終了日含まず)
  my $delta_days = ($epoch1 - $epoch2) / $SECS_PER_DAY;

  # 符号
  my $sign = $delta_days < 0 ? -1 : 1;

  # 終了日もカウントする
  return $sign * (abs($delta_days) + 1);
}

【theme : プログラミング
【genre : コンピュータ

プロフィール

よしいず

Author:よしいず
MATHEMATICS.PDFというウェブサイトを運営しています。

管理の都合上、トラックバックとコメントはオフにしてあります。ブログ経験者なら分かっていただけると思いますが、スパム(アダルトやその他の宣伝)ばかりなのが現実です。

リンクは自由です。当サイトの記事に対する間違いの指摘・意見・感想などを述べた記事からのリンクは歓迎です。ただし、ブログ記事アップ直後はミスが多く、頻繁に修正します。場合によっては削除する可能性もあります。その際、何も断りもなく修正・削除しますがご了承ください。内容を参考にする場合には投稿後一週間ほど様子を見てからにしてください(笑)。

記事の間違いを指摘するときは、その具体的箇所、理由(仕様に反するなど)・根拠(参考にした文献など)、代替案(同じ結果を得るための正しいやり方)も教えてください。そうしないと、(指摘される側および第三者はその時点では無知の状態なので、)どこが間違いなのか分かりませんし、本当に間違っているのかどうかが判断・検証できません。実際、間違いだと指摘されたことが結局は正しかったというケースもありますので。

このブログのタイトル一覧

リンク
月別アーカイブ
カテゴリ
最新記事
検索フォーム
RSSリンクの表示
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。