[php][PEAR]Date_Holidays_Driver::setYear()が変
正確に言うと、Date_Holidays_Driver_Japanese::setYear()の挙動が変。
※PEAR::Date_Holidays_Driver_Japanese 0.2.2がリリースされました。下記不具合を包括的に解決しています。0.2.0以前を使用してる方は、アップグレードすることを強くお勧めします。
Date_Holidaysクラスのfactory()メソッドはDriver名を指定するのと同時に、西暦を指定して祝日リストを生成します。西暦を指定していない場合は、内部で自動的に現在の西暦が採用されます。もし西暦が違う祝日を一緒に扱う場合(たとえば2008年と2009年)、ドライバをもう1度生成し、翻訳ファイルを登録しなければなりません。
それは面倒だと思って、APIドキュメントをあさっていると、Date_Holidays_Driver::setYear()というメソッドを見つけました。どうやら、西暦をセットしなおした上で祝日の再構築を行ってくれるようです。エンドユーザー・マニュアルがないので100%とは言い切れませんが、ソースコードからはそう判断できます。
で、早速使ってみたソースコードがこちら。
-
/**
-
* Date_Holidays_Driver_Japanseを用いて
-
* 祝日名を取得する(挙動がおかしい)
-
*
-
* 2008/05/11
-
*
-
* Author: uechoco
-
* 動作確認: PHP 5.2.5
-
* require: Date_Holidays (推奨バージョン:0.18.0)
-
* require: Date_Holidays_Driver_Japanese 0.2.0
-
*
-
*/
-
-
// Date_Holidaysクラスの読み込み
-
require_once "Date/Holidays.php";
-
-
// 言語ファイルの読み込み(PEARのdataディレクトリ内)
-
-
// Date_Holidaysオブジェクトの生成(西暦を省略すると現在の西暦になる)
-
$obj =& Date_Holidays::factory('Japanese');
-
if (Date_Holidays::isError($obj)) {
-
}
-
-
// 翻訳ファイルをロケール=ja_JPとして登録
-
$obj->addTranslationFile(LANG_FILE . '/Japanese/ja_JP.xml', 'ja_JP');
-
if (Date_Holidays::isError($obj)) {
-
}
-
-
$lastYear = 0;
-
for ($i = 0; $i <731; $i++) {
-
$t = $beginTime + $i * 86400;
-
// 西暦が更新されたら祝日の再構成
-
if ($lastYear != $y) {
-
$lastYear = $y;
-
//デバッグ用にオブジェクトを直接吐く
-
//echo "
-
-
<hr /><span style="color: red;">\n\n";
-
//print_r($obj->_internalNames);
-
//echo "</span>
-
-
<hr />\n\n";
-
-
}
-
-
$holiday = $obj->getHolidayForDate($d, 'ja_JP');
-
if (!is_null($holiday))
-
printHolidayInfo($holiday, $d);
-
}
-
-
function printHolidayInfo($holiday, $date = '')
-
{
-
echo $date . " =========
-
\n";
-
printf("名前:%s
-
\n", $holiday->getTitle());
-
//printf("内部名:%s
-
\n", $holiday->getInternalName());
-
//printf("プロパティ:%s
-
\n", print_r($holiday->getProperties(), true));
-
\n", print_r($holiday->getDate(), true));
-
}
-
exit;
-
?>
で、出力結果がこちら。
-
2008-01-01 =========
-
名前:元日
-
2008-01-14 =========
-
名前:成人の日
-
2008-02-11 =========
-
名前:建国記念の日
-
2008-03-20 =========
-
名前:春分の日
-
2008-04-29 =========
-
名前:昭和の日
-
2008-05-03 =========
-
名前:憲法記念日
-
2008-05-04 =========
-
名前:みどりの日
-
2008-05-05 =========
-
名前:こどもの日
-
2008-07-21 =========
-
名前:海の日
-
2008-09-15 =========
-
名前:敬老の日
-
2008-09-23 =========
-
名前:秋分の日
-
2008-10-13 =========
-
名前:体育の日
-
2008-11-03 =========
-
名前:文化の日
-
2008-11-23 =========
-
名前:勤労感謝の日
-
2008-12-23 =========
-
名前:天皇誕生日
-
2009-01-01 =========
-
名前:元日
-
2009-01-12 =========
-
名前:成人の日
-
2009-02-11 =========
-
名前:建国記念の日
-
2009-03-20 =========
-
名前:春分の日
-
2009-04-29 =========
-
名前:昭和の日
-
2009-05-03 =========
-
名前:憲法記念日
-
2009-05-04 =========
-
名前:みどりの日
-
2009-05-05 =========
-
名前:こどもの日
-
2009-07-20 =========
-
名前:海の日
-
2009-09-21 =========
-
名前:敬老の日
-
2009-09-23 =========
-
名前:秋分の日
-
2009-10-12 =========
-
名前:体育の日
-
2009-11-03 =========
-
名前:文化の日
-
2009-11-23 =========
-
名前:勤労感謝の日
-
2009-12-23 =========
-
名前:天皇誕生日
パッと見でよさそうに見えますが、よく見てみると、振替休日と国民の休日が表示されていないことに気がつきます。動作確認環境はWindows/XAMPP PHP5.2.5です。
少しだけ動作確認してみました。
★まず、オブジェクトを西暦が変わるたびに生成しなおすと、正常な結果になります。
-
$lastYear = 0;
-
for ($i = 0; $i <731; $i++) {
-
$t = $beginTime + $i * 86400;
-
// 西暦が更新されたら祝日の再構成
-
if ($lastYear != $y) {
-
// 西暦を指定してDate_Holidaysオブジェクトの生成
-
$obj =& Date_Holidays::factory('Japanese', $y);
-
if (Date_Holidays::isError($obj)) {
-
}
-
// 翻訳ファイルをロケール=ja_JPとして登録
-
$obj->addTranslationFile(LANG_FILE . '/Japanese/ja_JP.xml', 'ja_JP');
-
if (Date_Holidays::isError($obj)) {
-
}
-
$lastYear = $y;
-
}
-
$holiday = $obj->getHolidayForDate($d, 'ja_JP');
-
printHolidayInfo($holiday, $d);
-
}
★setYear()の直後に、$obj->_internalNamesを吐き出してみると、serYear()する度に$_internalNames配列が初期化されておらず、末尾に追加されていることがわかります。おそらく、$objに含まれる他のプロパティにも似たような現象が見られるかもしれません。
-
Array
-
(
-
[0] => newYearsDay
-
[1] => comingOfAgeDay
-
[2] => nationalFoundationDay
-
[3] => Vernal Equinox Day
-
[4] => showaDay
-
[5] => constitutionMemorialDay
-
[6] => greeneryDay
-
[7] => childrensDay
-
[8] => marineDay
-
[9] => respectfortheAgedDay
-
[10] => autumnalEquinoxDay
-
[11] => healthandSportsDay
-
[12] => nationalCultureDay
-
[13] => laborThanksgivingDay
-
[14] => emperorsBirthday
-
[17] => newYearsDay
-
[18] => comingOfAgeDay
-
[19] => nationalFoundationDay
-
[20] => Vernal Equinox Day
-
[21] => showaDay
-
[22] => constitutionMemorialDay
-
[23] => greeneryDay
-
[24] => childrensDay
-
[25] => marineDay
-
[26] => respectfortheAgedDay
-
[27] => autumnalEquinoxDay
-
[28] => healthandSportsDay
-
[29] => nationalCultureDay
-
[30] => laborThanksgivingDay
-
[31] => emperorsBirthday
-
[32] => substituteHolidayForgreeneryDay
-
[33] => substituteHolidayForlaborThanksgivingDay
-
)
-
Array
-
(
-
[0] => newYearsDay
-
[1] => comingOfAgeDay
-
[2] => nationalFoundationDay
-
[3] => Vernal Equinox Day
-
[4] => showaDay
-
[5] => constitutionMemorialDay
-
[6] => greeneryDay
-
[7] => childrensDay
-
[8] => marineDay
-
[9] => respectfortheAgedDay
-
[10] => autumnalEquinoxDay
-
[11] => healthandSportsDay
-
[12] => nationalCultureDay
-
[13] => laborThanksgivingDay
-
[14] => emperorsBirthday
-
[17] => newYearsDay
-
[18] => comingOfAgeDay
-
[19] => nationalFoundationDay
-
[20] => Vernal Equinox Day
-
[21] => showaDay
-
[22] => constitutionMemorialDay
-
[23] => greeneryDay
-
[24] => childrensDay
-
[25] => marineDay
-
[26] => respectfortheAgedDay
-
[27] => autumnalEquinoxDay
-
[28] => healthandSportsDay
-
[29] => nationalCultureDay
-
[30] => laborThanksgivingDay
-
[31] => emperorsBirthday
-
[34] => newYearsDay
-
[35] => comingOfAgeDay
-
[36] => nationalFoundationDay
-
[37] => Vernal Equinox Day
-
[38] => showaDay
-
[39] => constitutionMemorialDay
-
[40] => greeneryDay
-
[41] => childrensDay
-
[42] => marineDay
-
[43] => respectfortheAgedDay
-
[44] => autumnalEquinoxDay
-
[45] => nationalHolidayBeforeAutumnalEquinoxDay
-
[46] => healthandSportsDay
-
[47] => nationalCultureDay
-
[48] => laborThanksgivingDay
-
[49] => emperorsBirthday
-
[50] => substituteHolidayForconstitutionMemorialDay
-
)
setYear()を使うと振替休日と国民の休日だけ表示されないので、Date_Holidays_Driver_Japaneseがおかしいのかな?って思ったりもしたんですが、内部名が初期化されていないのはDate_Holidays_Driverもおかしい気がしないでもないのですが、今眠くて深追いする気が起きません(ぉぃ。
解決策としては、西暦が変わったら、オブジェクトを新規に生成しなおすのが早そうです。