一覧 |
コード登録画面
時間処理モジュール [ 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($time, get_class($this)) : ($c < 0);
}
/**
* 指定された時間とこの時間を比較します.
* もしもこのオブジェクトが持つ時間フィールドすべてが
* 引数のオブジェクトの時間フィールドと一致した場合、
* より多くの時間フィールドを持つほうが「後」となります.
* 例: 2004年(yearオブジェクト) < 2004年1月(monthオブジェクト)
*/
function after($time){
if(!is_a($time, 'time')) return FALSE;
$c = 0 < $this->compare_to($time);
return ($c == 0) ? is_subclass_of($this, get_class($time)) : (0 < $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($format, 0, 4);
$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->year, 1);
return $month;
}
/**
* このオブジェクトを date 型にキャストします.
* この年の 1月1日 を表す date オブジェクトを返します.
*/
function to_date(){
$date = new date($this->year, 1, 1);
return $date;
}
/**
* このオブジェクトを datetime 型にキャストします.
* この年の 1月1日0時0分を表す datetime オブジェクトを返します.
*/
function to_datetime(){
$datetime = new datetime($this->year, 1, 1, 0, 0);
return $datetime;
}
/**
* このオブジェクトを timestamp 型にキャストします.
* この年の 1月1日0時0分0秒を表す timestamp オブジェクトを返します.
*/
function to_timestamp(){
$ts = new timestamp($this->year, 1, 1, 0, 0, 0);
return $ts;
}
/**
* この date がうるう年かどうかを返します.
* うるう年の判別ルールは以下の通りです.
* - 4で割り切れるはうるう年である
* - ただし、100で割り切れる年はうるう年ではない
* - ただし、400で割り切れる年はうるう年である
*/
function is_leap_year(){
if($this->year % 4 != 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($format, 0, 4);
$month = substr($format, 5, 2);
$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->year, 1, 12);
return;
}
// 月が12より大きい場合は、年の繰上げ調整をします.
if(12 < $this->month){
$this->move_up(&$this->month, &$this->year, 1, 12);
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->month, 2, '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->month, 1);
return $date;
}
function to_datetime(){
$dt = new datetime($this->year, $this->month, 1, 0, 0);
return $dt;
}
function to_timestamp(){
$ts = new timestamp($this->year, $this->month, 1, 0, 0, 0);
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($format, 0, 4);
$month = substr($format, 5, 2);
$date = substr($format, 8, 2);
$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->date, 0, 0);
return $dt;
}
function to_timestamp(){
$ts = new timestamp($this->year, $this->month, $this->date, 0, 0, 0);
return $ts;
}
/**
* この日付の曜日を返します.
* 0 は日曜日, 6 は土曜日を表します.
*/
function get_day(){
static $m_sub = array(0, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4);
$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, 0, 4);
$month = substr($format, 5, 2);
$date = substr($format, 8, 2);
$hour = substr($format, 11, 2);
$min = substr($format, 14, 2);
$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->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;
}
}
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->min, 0);
return $ts;
}
}
/**
* 秒を含む時刻を表すクラスです.
*/
class timestamp extends datetime{
/**
* 秒を表す整数です.
*/
var $sec;
function format($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);
$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->min, 0, 59);
return;
}
if(59 < $this->sec){
$this->move_up(&$this->sec, &$this->min, 0, 59);
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