一覧 |
コード登録画面
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, 0, 4);
$month = substr($format, 5, 2);
$date = substr($format, 8, 2);
$hour = substr($format, 11, 2);
$min = substr($format, 14, 2);
$sec = substr($format, 17, 2);
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 (0 <= $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->year, 1, 12);
return;
}
if(12 < $this->month){
$this->move_up(&$this->month, &$this->year, 1, 12);
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->date, 0, 23);
return;
}
if(23 < $this->hour){
$this->move_up(&$this->hour, &$this->date, 0, 23);
return;
}
if($this->min < 0){
$this->move_down(&$this->min, &$this->hour, 0, 59);
return;
}
if(59 < $this->min){
$this->move_up(&$this->min, &$this->hour, 0, 59);
return;
}
if($this->sec < 0){
$this->move_down(&$this->sec, &$this->min, 0, 59);
return;
}
if(59 < $this->sec){
$this->move_up(&$this->sec, &$this->min, 0, 59);
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 % 4 != 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->month, 2, '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