Date_Holidays 0.20.1 (alpha)
Date_Holidays_Japan 0.1.0 (alpha)
PHPに限らずプログラマーにとって休日判定は頭の痛い問題のひとつです。
元日や春分秋分などの固定された日はまだいいとして、面倒なのが年によって日付が変更になる休日です。
体育の日を10月10日以外に変更するとかいう愚行のせいで、ある年までは祝日を固定にして、それ以降は毎年祝日を算出する必要があります。
また振替休日のチェックも面倒です。
例によってPearに祝日を扱うクラスがあるので使用してみましょう。
Pear::Date_Holidaysで祝日を扱うことが出来ます。
α版だけあって融通の利かない部分もあるのですが、祝日判定を間違うような致命的なバグは無いようですので使ってみましょう。
こちらはプラグイン的に言語を追加できるのですが、つい先日の2008/08/23に日本語言語ファイルであるところのDate_Holidays_Japanが追加されました。
いつものように解凍した後Date_Holidays_JapanフォルダをDate_Holidaysフォルダに上書きコピーし、フォルダ名をDateと変更します。
holiday.class.php
<?php //初期設定 define('CURRENT_DIR',getcwd().'/'); define('PEAR_DIR',$_SERVER['DOCUMENT_ROOT'].'/src/php/pear/'); ini_set('include_path',PEAR_DIR.PATH_SEPARATOR.ini_get('include_path')); require_once(PEAR_DIR.'Date/Holidays.php'); class pearHolidayModel { //メンバ変数 private $japan = array(); //コンストラクタ public function __construct($year=null){ $this->japan = &Date_Holidays::factory('Japan',$year,'ja_JP'); $this->japan->addTranslationFile(PEAR_DIR . 'Date/lang/Japan/ja_JP.xml', 'ja_JP'); if (Date_Holidays::isError($this->japan)){die('ファクトリでドライバオブジェクトを作成できませんでした');} } //一年の全祝日取得 public function getHolidays($year){ if(is_null($year)){$year=date('Y');} $this->japan->setYear($year); return $this->japan->getHolidays(); } //祝日ならその情報を取得//祝日でなかったらNULL public function getHolidayForDate($date=null){ if(is_null($date)){$date=date('Y-m-d');} return $this->japan->getHolidayForDate($date); } #↓クラスのおわり } |
Date_Holidaysはfactoryでインスタンスを作成します。
話は変わりますがどうもこのFactoryMethodパターンが理解できないのでどなたか教えてください。
利用側では常にインターフェイスのfactoryを呼んでおいてfactoryで実装クラスをnewすれば、実装クラスのメソッド名を変更してもfactoryを変更するだけで利用側を変える必要が無くて楽ちん、という理解で大丈夫なの?
以下簡単にメソッドを紹介すると、コンストラクタで国名と年を引き渡して祝日を決定します。
setYearで年を変更し、getHolidaysでその年の全祝日を取得します。
isHolidayは引数の日付が祝日かどうかを判定します。
getHolidayで祝日名から情報を取得、getHolidayForDateで日付から情報を取得します。
getHolidaysForDatespanで特定の期間中の祝日を取得、ということも出来るようです。
祝日を追加する関数については、_addStaticHolidays、_addHoliday、_addTranslationForHoliday、_addStringPropertyForHoliday、_addStringPropertiesForHoliday等ありますが違いがよくわからないし_なので触らぬほうがよさげ。
で、肝心のセットする関数がどれかはわかりませんでした。
デフォルトでは記念日名が英語ですが、addTranslationFileでDate_Holidays_Japanに入っていた言語ファイルを追加しています。
これを適用することで祝日名を日本語で取得することが可能になります。
さて呼び出してみましょう。
holiday.php
<?php #初期設定 header("Content-type: text/html; charset=utf-8"); require_once('./holiday.class.php'); $holiday = new pearHolidayModel(); $day='2007-01-01'; $today=$holiday->getHolidayForDate($day); var_dump($today); |
NULL
あれ?
日付から休日情報を取得するgetHolidayForDateは、引数にはY-m-dを要求するのにそれを見ていません。
setYearでセットした年とgetHolidayForDateに引き渡した年が違う場合、常にNULLが返ってきます。
isHolidayのほうはしっかり年もチェックしているのに。
見比べてみたところ、isHolidayには入っている以下のようなルーチンがgetHolidayForDateには入っていませんでした。
$compare_year = $date->getYear(); $this_year = $this->getYear(); if ($this_year !== $compare_year) { $this->setYear($compare_year); } |
このままでは不便きわまりないのでholiday.class.phpを変更。
//休日ならその情報を取得//祝日でなかったらNULL public function getHolidayForDate($date=null){ if(is_null($date)){$date=date('Y-m-d');} $year=explode('-',$date); $this->japan->setYear($year[0]); return $this->japan->getHolidayForDate($date); } |
これで年間の全祝日の取得、および日付から祝日情報を取得できるようになりました。
他にも必要なものがあればその都度追加しましょう。
つうかこのクラスは中身がよくわかんないんだよなあ…
何に使うのかよくわからないメソッドや定数がいっぱいあるし。