Perl 日付の計算方法

 Perlではtime関数で1970年1月1日0時0分からの経過秒を取得でき、その値をlocaltime関数を通す事で「年/月/日/曜日/時間/分/秒」に変換する事ができますが、逆に「年/月/日/曜日/時間/分/秒」から秒に戻す事は出来ないので関数を考えてみました。
 time()+localtime()で得られた日時を、本スプリクトで変換すれば time()の値と同じになります。

※新バージョンはこちら

sub ymdhns2time{
  my($i,$uru,$output);
  my $ye=$_[0];  #年 1970以上
  my $mo=$_[1];  #月 1~12
  my $da=$_[2];  #日 1~31(月によって異なる)
  my $ho=$_[3];  #時 0~23
  my $mi=$_[4];  #分 0~59
  my $se=$_[5];  #秒 0~59
  my $diff=$_[6]; #時差 -86399~86399 時差

  #各引数にデータが無い場合は
  if($ye eq ""){$ye=1970;}
  if($mo eq ""){$mo=1;}
  if($da eq ""){$da=1;}
  if($ho eq ""){$ho=0;}
  if($mi eq ""){$mi=0;}
  if($se eq ""){$se=0;}
  if($diff eq ""){$diff=0;}
  #引数のエラーチェック
  if($ye !~ /^[0-9]+$/){return(-1);}
  if($ye<1970){return(-1);}
  if($mo !~ /^[0-9]+$/){return(-1);}
  if($mo<1){return(-1);}
  if($mo>12){return(-1);}
  if($da !~ /^[0-9]+$/){return(-1);}
  if($da<1){return(-1);}
  if($ho !~ /^[0-9]+$/){return(-1);}
  if($ho<0){return(-1);}
  if($ho>23){return(-1);}
  if($mi !~ /^[0-9]+$/){return(-1);}
  if($mi<0){return(-1);}
  if($mi>59){return(-1);}
  if($se !~ /^[0-9]+$/){return(-1);}
  if($se<0){return(-1);}
  if($se>59){return(-1);}
  if($diff !~ /^[+-]?[0-9]+$/){return(-1);}
  if($diff<-86399){return(-1);}
  if($diff>86399){return(-1);}
  $uru=0;
  if($ye % 4 == 0){
    $uru=1;
    if($ye % 100 == 0){
      if($ye % 400 != 0){$uru=0;}
    }
  }
  if(($mo==1)&&($da>31)){return(-1);}
  if($uru==1){ #うるう年
    if(($mo==2)&&($da>29)){return(-1);}
  }else{
    if(($mo==2)&&($da>28)){return(-1);}
  }
  if(($mo==3)&&($da>31)){return(-1);}
  if(($mo==4)&&($da>30)){return(-1);}
  if(($mo==5)&&($da>31)){return(-1);}
  if(($mo==6)&&($da>30)){return(-1);}
  if(($mo==7)&&($da>31)){return(-1);}
  if(($mo==8)&&($da>31)){return(-1);}
  if(($mo==9)&&($da>30)){return(-1);}
  if(($mo==10)&&($da>31)){return(-1);}
  if(($mo==11)&&($da>30)){return(-1);}
  if(($mo==12)&&($da>31)){return(-1);}

  #年の処理(1970からの経過秒+前年までのうるう年の秒数)
  $output=($ye-1970)*31536000;
  for($i=1970;$i<$ye;$i++){
    if($i % 4 == 0){
      if(($i % 100 == 0)&&($i % 400 != 0)){
        #平年
      }else{
        $output=$output+86400; #うるう年(1日加算)
      }
    }    
  }
  #月の処理(1月は年で処理しているので不要)
  if    ($mo==2){$output=$output+2678400;
  }elsif($mo==3){$output=$output+5097600;
  }elsif($mo==4){$output=$output+7776000;
  }elsif($mo==5){$output=$output+10368000;
  }elsif($mo==6){$output=$output+13046400;
  }elsif($mo==7){$output=$output+15638400;
  }elsif($mo==8){$output=$output+18316800;
  }elsif($mo==9){$output=$output+20995200;
  }elsif($mo==10){$output=$output+23587200;
  }elsif($mo==11){$output=$output+26265600;
  }elsif($mo==12){$output=$output+28857600;
  }
  if($uru==1){  #うるう年の3月以降は1日加算
    if($mo>=3){$output=$output+86400;}
  }
  #日の処理
  $output=$output+($da-1)*86400;
  #時の処理
  $output=$output+$ho*3600;
  #分の処理
  $output=$output+$mi*60;
  #秒の処理
  $output=$output+$se;
  #時差の処理
  $output=$output-$diff;
  #時差でマイナスになった時は-1
  if($output<0){return(-1)}

  return($output);
}

使い方
 &ymdhns2time(年,月,日,時,分,秒,時差);
 で1970年1月1日0時0分を0秒とした秒数を返します。
 ・年は1970以降の西暦4桁
 ・時は0~23時の24時間制
 ・時差は-86399~86399の範囲で秒で記入、日本の場合はUTC+9時間なので32400と入力
 年,月,日,時,分,秒,時差が規定外の時は-1を返します。
 
 例えば、2000年1月1日 13時30分0秒の秒数が知りたければ
 $min=&ymdhns2time(2001,1,1,13,30,0,32400);
 とすれば$minに秒数が代入されます。

 引数を""や省略すると年=1970、月=1、日=1、時=0、分=0、秒=0、時差=0となります。
 ・&ymdhns2time();なら
 =1970/1/1 00:00:00(時差0)と同等→0
 ・&ymdhns2time("",2,"","","","",32400);なら
 =1970/2/1 00:00:00(時差+9時間)と同等→2646000
 不要な項目は入れなくても計算できるので、年を指定しない日付だけの計算や、時間だけの計算なども可能です。
 ただし年を入れない場合はうるう年に注意が必要です。1970年はうるう年では無いので1年365日で計算されます。


概要
 前半は引数のエラーチェックで後半が計算式。
 計算式は原始的に1970年からの秒数を加算してます。。
・1分は60秒
・1時間は3,600秒
・1日は86,400秒
・1年は31,536,000秒(うるう年は+86,400秒)
 なので
 1970年1月1日0時0分を0秒として、1日後なら86,400秒、1年後なら31,536,000秒と言う感じです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA