Date_Holidays_Driver_Japaneseを使ってみるとか2

PEAR::Date_Holidays_Driver_Japanese直してみた

早速使ってみたよ!

で気付いたところを折角なので。。。

[php] <?php ini_set('display_errors', 'On'); ini_set('memory_limit', -1); require_once('Date/Holidays.php');

$obj =& Date_Holidays::factory('Japanese',2008); $sec = time(); for ($i=0;$i<365;$i++) { $t = mktime(0,0,0,1,$i+1,2008); $date = date('Y-m-d', $t); if ($obj->isHoliday($date)) { // echo " holiday\n"; } if ($i % 10 == 0) { echo "[{$date}][" . memory_get_usage() / (1024*1024) . "M]"; echo "[" . (time() - $sec ) . "s]\n"; $sec = time(); } }[/php]
実行してみた。

$ php -q d.php
[2008-01-01][1.5150375366211M][0s]
[2008-01-11][1.6816329956055M][0s]
[2008-01-21][2.049934387207M][0s]
[2008-01-31][2.6353912353516M][1s]
[2008-02-10][3.4495162963867M][0s]
[2008-02-20][4.4876708984375M][1s]
[2008-03-01][5.7306900024414M][2s]
[2008-03-11][7.2339935302734M][3s]
[2008-03-21][8.9179916381836M][5s]
[2008-03-31][10.822479248047M][8s]
[2008-04-10][13.009956359863M][11s]
[2008-04-20][15.355422973633M][17s]

怖くなったので、このへんで Ctrl+C

うーん。なんかメモリをどんどん消費していくような。

でそもそもの Date/Holidays/Driver.php だけど、

[php] function isHoliday($date, $filter = null) { if (! is_a($date, 'Date')) { $date = $this->_convertDate($date); if (Date_Holidays::isError($date)) { return $date; } }

    //rebuild internal array of holidays if required.
    $compare_year = $date->getYear();
    $this_year = $this->getYear();
    if ($this_year !== $compare_year) {
        $this->setYear($compare_year);
    }

    if (is_null($filter)) {
        $filter = new Date_Holidays_Filter_Blacklist(array());
    } elseif (is_array($filter)) {
        $filter = new Date_Holidays_Filter_Whitelist($filter);
    }

    foreach (array_keys($this->_dates) as $internalName) {
        if ($filter->accept($internalName)) {
            if (Date_Holidays_Driver::dateSloppyCompare($date,
                                      $this->_dates[$internalName]) != 0) {
                continue;
            }
            $this->setYear($this_year);
            return true;
        }
    }
    $this->setYear($this_year);
    return false;
}

function setYear($year)
{
    $this->_year = $year;
    return $this->_buildHolidays();
}[/php]


毎回、setYear => _buildHolidays を呼び出しているのがガンかな。。。

どうしたもんだかという感じですが、とりあえず、
$obj = & Date_Holidays::factory('Japanese',2008);
で生成された $obj を static とかで使いまわさずに毎回呼び出せばメモリも増えないのでそれで対応。

ってか、そもそも最近対応したバグ修正から派生してるっぽいから、まだ気付いてないのかな。
Bug #13395 isHoliday resets interal year storage