CodeVault (ユーザ投稿コードライブラリ) ポータルトップ | phpspot

  一覧 | コード登録画面
前のページに戻る
Calendar クラス [ 2005年05月05日 ]
<?php
/*
 * Calendar クラス
 *  スクリプトの概要
 *  時間の操作を行うためのクラスです.
 *  もしも Java を知っている方であれば、
 *  java.util.Calendar の PHP バージョン 
 *  だと思っていただければ良いでしょう。
 *
 *  作成者: Hawk
 *   
 *  使い方(例):
 *  // 1週間前の年月日を出力します.
 *  $cal = new calendar();
 *  $cal->date -= 7;
 *  $cal->adjust();
 *  print $cal->year.'/'.$cal->month.'/'.$cal->date;
 */

/**
 * 時間を操作するためのクラスです.
 * 日付の解釈のしかたは、グレゴリオ暦に基づきます.
 */
class calendar{
  
/**
   * 年を表す整数です.
   */
  
var $year;
  
  
/**
   * 月を表す整数です.
   * この値は 1 <= $month <= 12 の間に調整されます.
   */
  
var $month;
  
  
/**
   * 日を表す整数です.
   * この値は 1 <= $date <= ($this->get_date_count()) の間に調整されます.
   */
  
var $date;
  
  
/**
   * 時を表す整数です.
   * この値は 0 <= $hour <= 23 の間に調整されます.
   */
  
var $hour;
  
  
/**
   * 分を表す整数です.
   * この値は 0 <= $min <= 59 の間に調整されます.
   */
  
var $min;
  
  
/**
   * 秒を表す整数です.
   * この値は 0 <= $sec <= 59 の間に調整されます.
   */
  
var $sec;
  
  
/**
   * 指定された時間を示す calendar オブジェクトを構築します.
   * 引数が指定されない場合、保持する時間の情報は現在のものとなります.
   * @param $format 'YYYY-mm-dd HH:ii:ss' 形式の文字列
   */
  
function calendar($format NULL){
    
// フォーマットが指定された場合は、そのフォーマットが示す時間を表す calendar を構築する
    
if(isset($format)){
      
$year  substr($format,  04);
      
$month substr($format,  52);
      
$date  substr($format,  82);
      
$hour  substr($format112);
      
$min   substr($format142);
      
$sec   substr($format172);
      if(
$this->validate($year) && $this->validate($month) && $this->validate($date) &&
         
$this->validate($hour) && $this->validate($min) && $this->validate($sec)){
        
$this->year  intval($year);
        
$this->month intval($month);
        
$this->date  intval($date);
        
$this->hour  intval($hour);
        
$this->min   intval($min);
        
$this->sec   intval($sec);
        
$this->adjust();
      }else{
        
trigger_error('不正なフォーマットです."YYYY-mm-dd HH:ii:ss"という書式でなければなりません('.$format.')');
      }
    }
    
// フォーマットが指定されない場合は、現在時刻を表す calendar を構築する
    
else{
      
$this->year  intval(date('Y'));
      
$this->month intval(date('n'));
      
$this->date  intval(date('j'));
      
$this->hour  intval(date('G'));
      
$this->min   intval(date('i'));
      
$this->sec   intval(date('s'));
    }
  }
  
  
/**
   * 解析されたフォーマットの値が妥当かどうかを返します.
   * 指定された値が0以上の整数である場合のみ TRUE を返します.
   * この function は、コンストラクタから呼び出されます.
   */
  
function validate($value){
    if(!
is_numeric($value)) return FALSE;
    return (
<= $value);
  }
  
  
/**
   * 時間の不整合を調整します. 調整は、大きな単位から順番に行われます. 
   * 例を以下に挙げます.
   *
   * 2005年4月31日 → 2005年5月1日
   * 2005年1月-1日 → 2004年12月30日
   * 2007年14月31日 → 2008年2月31日 → 2008年3月2日
   * 00:00:3666 → 00:61:06 → 01:01:06 (※1時間は3600秒です)
   */
  
function adjust(){
    if(
$this->month 1){
      
$this->move_down(&$this->month, &$this->year112);
      return;
    }
    if(
12 $this->month){
      
$this->move_up(&$this->month, &$this->year112);
      return;
    }
    if(
$this->date 1){
      while(
$this->date 1){
        
$this->month --;
        if(
$this->month == 0){
          
$this->month 12;
          
$this->year --;
        }
        
$this->date += $this->get_date_count();
      }
      
$this->adjust();
      return;
    }
    if(
$this->get_date_count() < $this->date){
      while(
$this->get_date_count() < $this->date){
        
$this->date -= $this->get_date_count();
        
$this->month ++;
        if(
$this->month == 13){
          
$this->month 1;
          
$this->year ++;
        }
      }
      
$this->adjust();
      return;
    }
    if(
$this->hour 0){
      
$this->move_down(&$this->hour, &$this->date023);
      return;
    }
    if(
23 $this->hour){
      
$this->move_up(&$this->hour, &$this->date023);
      return;
    }
    if(
$this->min 0){
      
$this->move_down(&$this->min, &$this->hour059);
      return;
    }
    if(
59 $this->min){
      
$this->move_up(&$this->min, &$this->hour059);
      return;
    }
    if(
$this->sec 0){
      
$this->move_down(&$this->sec, &$this->min059);
      return;
    }
    if(
59 $this->sec){
      
$this->move_up(&$this->sec, &$this->min059);
      return;
    }
  }
  
  
/**
   * 指定された値の繰り上げ処理を行います.
   * この function は、adjust() から呼び出されます.
   * @param &$field 調整対象の値(例えば "分")
   * @param &$upper_field 繰り上げ対象の値(例えば "時")
   * @param $min $field が取りうる最小値
   * @param $max $field が取りうる最大値
   */
  
function move_up(&$field, &$upper_field$min$max){
    if(
$field <= $max) return;
    
$range $max $min 1;
    
$amount intval(($field $min) / $range);
    
$upper_field += $amount;
    
$field = ($field $min) % $range $min;
    
$this->adjust();
  }
  
  
/**
   * 指定された値の繰り下げ処理を行います.
   * この function は、adjust() から呼び出されます.
   * @param &$field 調整対象の値
   * @param &$upper_field 繰り下げ対象の値
   * @param $min $field が取りうる最小値
   * @param $max $field が取りうる最大値
   */
  
function move_down(&$field, &$upper_field$min$max){
    if(
$min <= $field) return;
    
$range $max $min 1;
    
$amount intval(($min $field 1) / $range) + 1;
    
$upper_field -= $amount;
    
$field $max - ($min $field  1) % $range;
    
$this->adjust();
  }
  
  
/**
   * 指定された値とこの calendar を比較します.
   * 指定された値が calendar オブジェクトであり、
   * このオブジェクトと同じ時間を表す calendar である場合に TRUE を返します.
   */
  
function equals($cal){
    if(!
is_a($cal'calendar')) return FALSE;
    return 
      (
$this->year  == $cal->year) && 
      (
$this->month == $cal->month) &&
      (
$this->date  == $cal->date);
  }

  
/**
   * 指定された calendar とこの calendar を比較します.
   * @param cal このオブジェクトと比較される calendar オブジェクト 
   * @return この date の現在時刻が $date の時刻より前の場合は TRUE、
   *         そうでない場合はFALSE
   */
  
function before($cal){
    if(!
is_a($cal'calendar')) return FALSE;
    
$this->adjust();
    
$cal->adjust();
    if(
$this->year != $cal->year) return ($this->year $cal->year);
    if(
$this->month != $cal->month) return ($this->month $cal->month);
    return (
$this->date $cal->date);
  }

  
/**
   * 指定された calendar とこの calendar を比較します.
   * @param cal このオブジェクトと比較される calendar オブジェクト
   * @return この date の現在時刻が $date の時刻より後の場合は TRUE、
   *         そうでない場合はFALSE
   */
  
function after($cal){
    if(!
is_a($cal'calendar')) return FALSE;
    
$this->adjust();
    
$cal->adjust();
    if(
$this->year != $cal->year) return ($cal->year $this->year);
    if(
$this->month != $cal->month) return ($cal->month $this->month);
    return (
$date->date $cal->date);
  }

  
/**
   * この calendar がうるう年かどうかを返します.
   * うるう年の判断基準は以下の通りです.
   *   - 4で割り切れるはうるう年である
   *   - ただし、100で割り切れる年はうるう年ではない
   *   - ただし、400で割り切れる年はうるう年である
   */
  
function is_leap_year(){
    if(
$this->year != 0){
      return 
FALSE;
    }else if(
$this->year 100 != 0){
      return 
TRUE;
    }else{
      return (
$this->year 400 == 0);
    }
  }
  
  
/**
   * この calendar が示す月の日数を返します.
   */
  
function get_date_count(){
    switch(
$this->month){
    case 
1:
      return 
31;
    case 
2:
      return (
$this->is_leap_year()) ? 29 28;
    case 
3:
      return 
31;
    case 
4:
      return 
30;
    case 
5:
      return 
31;
    case 
6:
      return 
30;
    case 
7:
      return 
31;
    case 
8:
      return 
31;
    case 
9:
      return 
30;
    case 
10:  
      return 
31;
    case 
11:
      return 
30;
    case 
12:
      return 
31;
    default:
      
$this->adjust();
      return 
$this->get_date_count();
    }
  }

  
/**
   * この calendar の複製を返します.
   */
  
function clone(){
    
$cal = new calendar();
    
$cal->year  $this->year;
    
$cal->month $this->month;
    
$cal->date  $this->date;
    
$cal->hour  $this->hour;
    
$cal->min   $this->min;
    
$cal->sec   $this->sec;
    return 
$cal;
  }
  
  
/**
   * この calendar の文字列表現を返します.
   * この function は、自動的に adjust() を行います.
   */
  
function to_string(){
    
$this->adjust();
    
$year  str_pad($this->year,  4'0'STR_PAD_LEFT);
    
$month str_pad($this->month2'0'STR_PAD_LEFT);
    
$date  str_pad($this->date,  2'0'STR_PAD_LEFT);
    
$hour  str_pad($this->hour,  2'0'STR_PAD_LEFT);
    
$min   str_pad($this->min,   2'0'STR_PAD_LEFT);
    
$sec   str_pad($this->sec,   2'0'STR_PAD_LEFT);
    return 
$year .'-'.$month.'-'.$date.' '.$hour.':'.$min.':'.$sec;
  }
}
?>

投稿者:Hawk