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

  一覧 | コード登録画面
前のページに戻る
時間処理モジュール [ 2005年09月11日 ]
<?php
/**
 * 時間処理モジュール
 *  スクリプトの概要
 *  時間処理を行うモジュールです。
 *  PHP の date 関数は
 *  1901-12-13 20:45:54 から 2038-01-19 03:14:07 まで
 *  しか扱うことが出来ませんが
 *  (参考: http://www.php.net/manual/ja/function.date.php)
 *  このモジュールでは
 *  0000-01-01 00:00:00 から 9999-12-31 23:59:59 まで
 *  扱うことが出来ます。
 *  
 *  このモジュールは calendar クラスの改良版です。
 *  このモジュールでは必要に応じて様々なクラスを使い分ける
 *  ことができます。
 *  year      : 年を扱う場合
 *  month     : 年月を扱う場合
 *  date      : 年月日を扱う場合
 *  datetime  : 時刻(何時何分)を扱う場合
 *  timestamp : 時刻(何時何分何秒)を扱う場合
 *  
 *  
 *  作成者: Hawk
 *  
 *  使い方:
 *  // 今日の日付の1週間前の日付を取得します.
 *  $time = datetime_now();
 *  $time->date -= 7;
 *  $time->adjust();
 *  
 *  // 指定された日時を取得します.
 *  $time = new datetime(2005, 1, 2, 3, 4);
 *  print($time->to_string()); // 2005-01-02 03:04 を出力
 *  
 *  // 指定されたフォーマットが表す時刻を取得します.
 *  $str = '2005-09-09 09:09:09';
 *  $time = timestamp::format($str);
 *  
 *  // 日付の比較をします.
 *  $now = date_now();
 *  $time = new date(2005, 9, 15);
 *  if($now->before($time)){
 *    print('今日は2005年9月15日の前です。');
 *  }
 *  else{
 *    print('今日は2005年9月15日の後です。');
 *  }
 */

/**
 * 現在の年を表す year オブジェクトを返します.
 */
function year_now(){
  static 
$now;
  if(!isset(
$now)) $now = new year(date('Y'));
  return 
$now;
}

/**
 * 現在の月を表す month オブジェクトを返します.
 */
function month_now(){
  static 
$now;
  if(!isset(
$now)) $now = new month(date('Y'), date('n'));
  return 
$now;
}

/**
 * 現在の日付を表す date オブジェクトを返します.
 */
function date_now(){
  static 
$now;
  if(!isset(
$now)) $now = new date(date('Y'), date('n'), date('d'));
  return 
$now;
}

/**
 * 現在の時刻を表す datetime オブジェクトを返します.
 */
function datetime_now(){
  static 
$now;
  if(!isset(
$now)) $now = new datetime(date('Y'),date('n'),date('d'),date('H'),date('i'));
  return 
$now;
}

/**
 * 現在の秒単位の時刻を表す timestamp オブジェクトを返します.
 */
function timestamp_now(){
  static 
$now;
  if(!isset(
$now)) $now = new timestamp(date('Y'),date('n'),date('d'),date('H'),date('i'),date('s'));
  return 
$now;
}

/**
 * 時間を表すクラスの抽象基底クラスです.
 */
class time{
  
/**
   * 指定されたフォーマットが表す time オブジェクトを構築します.
   * フォーマットが不正な場合は NULL を返します.
   */
  
function format($format){
  }
  
  
/**
   * 時間の不整合を調整します.
   */
  
function adjust(){
  }

  
/**
   * メンバ変数を設定します. この function はコンストラクタから呼ばれます.
   * @param &$var このオブジェクトのメンバ変数
   * @param $value 指定されたメンバ変数に割り当てる値
   * @param $fieldname メンバ変数のフィールド名
   * @return 正常に値が設定された場合は TRUE
   */
  
function set_variable(&$var$value$fieldname){
    if(!
is_numeric($value)){
      
trigger_error($fieldname.'の値が不正です('.$value.')'E_USER_WARNING);
      return 
FALSE;
    }
    
$var intval($value);
    return 
TRUE;
  }
    
  
/**
   * この時間と指定された時間を比較します. 
   * このメソッドの順序付けは、equals と一貫性がありません.
   * この型の時間フィールドと引数の型の時間フィールドのうち、
   * 共通部分のフィールド同士を比較します.
   */
  
function compare_to($time){
  }
  
  
/**
   * 指定されたオブジェクトとこのオブジェクトを比較します.
   */
  
function equals($obj){
    if(
get_class($this) != get_class($obj)) return FALSE;
    return 
$this->compare_to($obj) == 0;
  }
  
  
/**
   * 指定された時間とこの時間を比較します.
   * もしもこのオブジェクトが持つ時間フィールドすべてが
   * 引数のオブジェクトの時間フィールドと一致した場合、
   * より多くの時間フィールドを持つほうが「後」となります.
   * 例: 2004年(yearオブジェクト) < 2004年1月(monthオブジェクト) < 2004年1月1日(date オブジェクト)
   */
  
function before($time){
    if(!
is_a($time'time')) return FALSE;
    
$c $this->compare_to($time);
    return (
$c == 0) ? is_subclass_of($timeget_class($this)) : ($c 0);
  }
  
  
/**
   * 指定された時間とこの時間を比較します.
   * もしもこのオブジェクトが持つ時間フィールドすべてが
   * 引数のオブジェクトの時間フィールドと一致した場合、
   * より多くの時間フィールドを持つほうが「後」となります.
   * 例: 2004年(yearオブジェクト) < 2004年1月(monthオブジェクト)
   */
  
function after($time){
    if(!
is_a($time'time')) return FALSE;
    
$c $this->compare_to($time);
    return (
$c == 0) ? is_subclass_of($thisget_class($time)) : ($c);
  }
  
  
/**
   * このオブジェクトの文字列表現を返します.
   */
  
function to_string(){
  }
  
  
/**
   * このオブジェクトを year 型にキャストします.
   */
  
function to_year(){
  }
  
  
/**
   * このオブジェクトを month 型にキャストします.
   */
  
function to_month(){
  }
  
  
/**
   * このオブジェクトを date 型にキャストします.
   */
  
function to_date(){
  }
  
  
/**
   * このオブジェクトを datetime 型にキャストします.
   */
  
function to_datetime(){
  }
  
/**
   * このオブジェクトを timestamp 型にキャストします.
   */
  
function to_timestamp(){
  }
}

/**
 * 年を表すクラスです.
 */
class year extends time{
  
/**
   * 年を表す整数です.
   */
  
var $year;
  
  
/**
   * 指定されたフォーマットが表す year オブジェクトを構築します.
   */
  
function format($format){
    
$year substr($format04);
    
$year_obj = @new year($year);
    return 
$year_obj;
  }
  
  
/**
   * 指定された年を表す year オブジェクトを構築します.
   */
  
function year($year){
    
$this->init($year);
    
$this->adjust();
  }
  
  
/**
   * メンバ変数の初期化処理を行います.
   */
  
function init($year){
    
$this->set_variable(&$this->year$year'年');
  }
  
  
/**
   * 年の値を4桁に調整します. 10000年問題に対応するまでの暫定的処置です.
   */
  
function adjust(){
    
$this->year %= 10000;
    if(
$this->year 0$this->year += 10000;
  }
  
  function 
compare_to($time){
    return (
is_a($time'year')) ? $this->year $time->year 0;
  }
  
  
/**
   * この時間の文字列表現を返します.
   */
  
function to_string(){
    
$year  str_pad($this->year,  4'0'STR_PAD_LEFT);
    return 
$year;
  }
  
  
/**
   * このオブジェクトを year 型にキャストします. 
   * 返り値は、このオブジェクトのクローンです.
   */
  
function to_year(){
    
$year = new year($this->year);
    return 
$year;
  }
  
  
/**
   * このオブジェクトを month 型にキャストします.
   * この年の 1月 を表す month オブジェクトを返します.
   */
  
function to_month(){
    
$month = new month($this->year1);
    return 
$month;
  }
  
/**
   * このオブジェクトを date 型にキャストします.
   * この年の 1月1日 を表す date オブジェクトを返します.
   */
  
function to_date(){
    
$date = new date($this->year11);
    return 
$date;
  }
  
  
/**
   * このオブジェクトを datetime 型にキャストします.
   * この年の 1月1日0時0分を表す datetime オブジェクトを返します.
   */
  
function to_datetime(){
    
$datetime = new datetime($this->year1100);
    return 
$datetime;
  }
  
  
/**
   * このオブジェクトを timestamp 型にキャストします.
   * この年の 1月1日0時0分0秒を表す timestamp オブジェクトを返します.
   */
  
function to_timestamp(){
    
$ts = new timestamp($this->year11000);
    return 
$ts;
  }
  
  
/**
   * この date がうるう年かどうかを返します.
   * うるう年の判別ルールは以下の通りです.
   *   - 4で割り切れるはうるう年である
   *   - ただし、100で割り切れる年はうるう年ではない
   *   - ただし、400で割り切れる年はうるう年である
   */
  
function is_leap_year(){
    if(
$this->year != 0) return FALSE;
    if(
$this->year 100 != 0) return TRUE;
    return (
$this->year 400 == 0);
  }
}

/**
 * 年月を表すクラスです.
 */
class month extends year{
  
/**
   * 月を表す整数です.
   */
  
var $month;
  
  
/**
   * 指定された年月を表す month オブジェクトを構築します.
   */
  
function format($format){
    
$year substr($format04);
    
$month substr($format52);
    
$month_obj = @new month($year$month);
    return 
$month_obj;
  }
  
  
/**
   * 指定された時間を表す month オブジェクトを構築します.
   */
  
function month($year$month){
    
$this->init($year$month);
    
$this->adjust();
  }
  
  function 
init($year$month){
    
parent::init($year);
    
$this->set_variable(&$this->month$month'月');
  }

  
/**
   * 指定された値の繰り上げ処理を行います.
   * この 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();
  }
  
  
/**
   * 年と月の不整合を調整します.
   */
  
function adjust(){
    
// 年の不整合を調整します.
    
parent::adjust();
    
    
// 月が1より小さい場合は、年の繰り下げ調整をします.
    
if($this->month 1){
      
$this->move_down(&$this->month, &$this->year112);
      return;
    }
    
    
// 月が12より大きい場合は、年の繰上げ調整をします.
    
if(12 $this->month){
      
$this->move_up(&$this->month, &$this->year112);
      return;
    }
  }
  
  function 
compare_to($time){
    
$c parent::compare_to($time);
    if(
$c != 0) return $c;
    return (
is_a($time'month')) ? $this->month $time->month 0;
  }

  
/**
   * このdate の文字列表現を返します.
   */
  
function to_string(){
    
$year  parent::to_string();
    
$month str_pad($this->month2'0'STR_PAD_LEFT);
    return 
$year .'-'.$month;
  }
  function 
to_month(){
    
$month = new month($this->year$this->month);
    return 
$month;
  }
  function 
to_date(){
    
$date = new date($this->year$this->month1);
    return 
$date;
  }
  function 
to_datetime(){
    
$dt = new datetime($this->year$this->month100);
    return 
$dt;
  }
  function 
to_timestamp(){
    
$ts = new timestamp($this->year$this->month1000);
    return 
$ts;
  }
  
  
/**
   * この月の日数を返します.
   */
  
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;
    }
  }
}

/**
 * 年月日の情報を保持するクラスです.
 */
class date extends month{
  
/**
   * 日を表す整数です.
   */
  
var $date;
  
  
/**
   * 指定されたフォーマットが表す date オブジェクトを返します.
   */
  
function format($format){
    
$year  substr($format04);
    
$month substr($format52);
    
$date  substr($format82);
    
$date_obj = @new date($year$month$date);
    return 
$date_obj;
  }
  
  function 
date($year$month$date){
    
$this->init($year$month$date);
    
$this->adjust();
  }
  
  function 
init($year$month$date){
    
parent::init($year$month);
    
$this->set_variable(&$this->date$date'日');
  }
  
  
/**
   * 年月日の不整合を調整します.
   * 2005年4月31日 → 2005年5月1日
   * 2005年1月-1日 → 2004年12月30日
   * 2004年14月31日 → 2005年2月31日 → 2005年3月3日
   */
  
function adjust(){
    
// 年と月の不整合を調整します.
    
parent::adjust();
    
    
// 日が1より小さい場合は、月の繰り下げ調整をします.
    
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;
    }
  }
  
  function 
compare_to($time){
    
$c parent::compare_to($time);
    if(
$c != 0) return $c;
    return (
is_a($time'date')) ? $this->date $time->date 0;
  }
  
  
/**
   * このdate の文字列表現を返します.
   */
  
function to_string(){
    
$month parent::to_string();
    
$date  str_pad($this->date,  2'0'STR_PAD_LEFT);
    return 
$month.'-'.$date;
  }
  function 
to_date(){
    
$date = new date($this->year$this->month$this->date);
    return 
$date;
  }
  function 
to_datetime(){
    
$dt = new datetime($this->year$this->month$this->date00);
    return 
$dt;
  }
  function 
to_timestamp(){
    
$ts = new timestamp($this->year$this->month$this->date000);
    return 
$ts;
  }
  
  
/**
   * この日付の曜日を返します.
   * 0 は日曜日, 6 は土曜日を表します.
   */
  
function get_day(){
    static 
$m_sub = array(0032503514624);
    
$y $this->year;
    
$m $this->month;
    
$d $this->date;
    if(
$m 3$y--;
    return (
$y intval($y/4) - intval($y/100) + intval($y/400) + $m_sub[$m] + $d) % 7;
  }
}

/**
 * 時刻を表すクラスです.
 */
class datetime extends date{
  
/**
   * 時を表す整数(0〜23)です.
   */
  
var $hour;
  
  
/**
   * 分を表す整数(0〜59)です.
   */
  
var $min;
  
  function 
format($format){
    
$year  substr($format,  04);
    
$month substr($format,  52);
    
$date  substr($format,  82);
    
$hour  substr($format112);
    
$min   substr($format142);
    
$datetime = @new datetime($year$month$date$hour$min);
    return 
$datetime;
  }
  
  function 
datetime($year$month$date$hour$min){
    
$this->init($year$month$date$hour$min);
    
$this->adjust();
  }
  
  function 
init($year$month$date$hour$min){
    
parent::init($year$month$date);
    
$this->set_variable(&$this->hour$hour'時');
    
$this->set_variable(&$this->min,  $min'分');
  }
  
  function 
adjust(){
    
parent::adjust();
    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;
    }
  }
  
  function 
compare_to($time){
    
$c parent::compare_to($time);
    if(
$c != 0) return $c;
    if(
is_a($time'datetime')){
      if(
$this->hour != $time->hour) return $this->hour $time->hour;
      if(
$this->min  != $time->min)  return $this->min  $time->min;
    }
    return 
0;
  }
  
  function 
to_string(){
    
$date parent::to_string();
    
$hour str_pad($this->hour,  2'0'STR_PAD_LEFT);
    
$min  str_pad($this->min,   2'0'STR_PAD_LEFT);
    return 
$date.' '.$hour.':'.$min;
  }
  function 
to_datetime(){
    
$dt = new datetime($this->year$this->month$this->date$this->hour$this->min);
    return 
$dt;
  }
  function 
to_timestamp(){
    
$ts = new timestamp($this->year$this->month$this->date$this->hour$this->min0);
    return 
$ts;
  }
}

/**
 * 秒を含む時刻を表すクラスです.
 */
class timestamp extends datetime{
  
/**
   * 秒を表す整数です.
   */
  
var $sec;
  
  function 
format($format){
    
$year  substr($format,  04);
    
$month substr($format,  52);
    
$date  substr($format,  82);
    
$hour  substr($format112);
    
$min   substr($format142);
    
$sec   substr($format172);
    
$timestamp = @new timestamp($year$month$date$hour$min$sec);
    return 
$timestamp;
  }
  
  function 
timestamp($year$month$date$hour$min$sec){
    
$this->init($year$month$date$hour$min$sec);
    
$this->adjust();
  }
  
  function 
init($year$month$date$hour$min$sec){
    
parent::init($year$month$date$hour$min);
    
$this->set_variable(&$this->sec$sec'秒');
  }
  
  function 
compare_to($time){
    
$c parent::compare_to($time);
    if(
$c != 0) return $c;
    return (
is_a($time'timestamp')) ? $this->sec $time->sec 0;
  }
  
  function 
adjust(){
    
parent::adjust();
    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 
to_string(){
    
$datetime parent::to_string();
    
$sec str_pad($this->sec,  2'0'STR_PAD_LEFT);
    return 
$datetime.':'.$sec;
  }
  function 
to_timestamp(){
    
$ts = new timestamp($this->year$this->month$this->date$this->hour$this->min$this->sec);
    return 
$ts;
  }
}

/**
 * 2つの時間オブジェクトを比較します.
 */
function compare_time($time1$time2){
  return 
$time1->compare_to($time2);
}
?>

投稿者:Hawk