PEAR::Calendar 0.5.4にバグ(レシピ075)
[レシピ075] カレンダーを表示したい(P.182~)のカレンダーの表示がおかしいというご指摘が読者の方よりありました。
確認したところ、本書のサンプルプログラム(03/03/14-1.php)では、例えば、2010年2月のカレンダーは以下のように表示され、正しくありませんでした。
正常な表示は、以下のようになります。
調査の結果、現在、以下が判明しています。
- これは、PEAR::Calendar 0.5.4のCalendar_Month_Weeksのバグである。
- PEAR::Calendarを0.5.3にすると正常に表示できる。
- PEAR::Calendar 0.5.4でも、Calendar_Month_Weekdaysを使うと正常に表示できる。
- PEAR::Calendar 0.5.4でも、2009年は正常に表示できる。
Calendar_Month_WeeksとCalendar_Month_Weekdaysを比較したサンプルコードは以下のようになります。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link href="14-2.css" rel="stylesheet" type="text/css" />
<title>カレンダーを表示したい</title>
</head>
<body>
<h2>Calendar_Month_Weeks</h2>
<?php
//---------------------------------------------------------------------
// Calendar_Month_Weeks を利用する場合(サンプル通り)
//---------------------------------------------------------------------
require_once 'Calendar/Month/Weeks.php';
# 曜日に表示する文字列とCSSクラス名を設定します。
$weekdayDefines = array(array('日', 'sunday'), array('月', 'monday'),
array('火', 'tuesday'), array('水', 'wednesday'),
array('木', 'thursday'), array('金', 'friday'),
array('土', 'saturday'));
# カレンダーの左側に表示させる曜日を設定します。
$weekdayBase = 0; // 0:日曜~6:土曜
# カレンダーに表示する年月を取得します。
// デフォルトの年月を設定
$year = (int) date('Y');
$month = (int) date('n');
// GETパラメータが指定されている場合は値を検証してから表示年月を取得
if (isset($_GET['year_month'])) {
$yyyymm = trim($_GET['year_month']);
// YYYYMM形式であれば年月を取得
if (preg_match('/^([12]\d{3})(1[012]|0[1-9])$/', $yyyymm, $match)) {
$year = (int) $match[1];
$month = (int) $match[2];
}
}
# カレンダーデータを生成します。
$calendar = new Calendar_Month_Weeks($year, $month, $weekdayBase);
$calendar->build();
# カレンダーの曜日部分を表示します。
$thisMonth = $calendar->thisMonth(TRUE); //今月
$prevMonth = $calendar->prevMonth(TRUE); //先月
$nextMonth = $calendar->nextMonth(TRUE); //来月
$prevMonthUrl = '?year_month=' . date('Ym', $prevMonth);
$nextMonthUrl = '?year_month=' . date('Ym', $nextMonth);
$thisMonthText = date('Y/m', $thisMonth);
?>
<table border="1">
<thead>
<tr>
<td><a href="<?php echo $prevMonthUrl;?>"><<</a></td>
<th colspan="5"><?php echo $thisMonthText;?></th>
<td><a href="<?php echo $nextMonthUrl;?>">>></a></td>
</tr>
<tr>
<?php
for ($i = 0; $i < 7; $i++) {
$weekday = ($weekdayBase + $i) % 7;
$weekdayText = $weekdayDefines[$weekday][0];
$weekdayClass = $weekdayDefines[$weekday][1];
echo '<th class="' . $weekdayClass . '">', $weekdayText, '</th>';
}
?>
</tr>
</thead>
<tbody>
<?php
# カレンダーの日付部分を表示します。
while ($days = $calendar->fetch()) {
$days->build();
$weekday = 0;
echo '<tr>';
while ($day = $days->fetch()) {
$weekdayClass = $weekdayDefines[$weekday][1];
if ($day->isEmpty()) {
$dayText = " ";
} else {
$dayText = $day->thisDay();
}
echo '<td class="' . $weekdayClass . '">', $dayText, '</td>';
$weekday++;
}
echo '</tr>';
}
?>
</tbody>
</table>
<h2>Calendar_Month_Weekdays</h2>
<?php
//---------------------------------------------------------------------
// Calendar_Month_Weekdays を利用する場合
//---------------------------------------------------------------------
require_once 'Calendar/Month/Weekdays.php';
# 曜日に表示する文字列とCSSクラス名を設定します。
$weekdayDefines = array(array('日', 'sunday'), array('月', 'monday'),
array('火', 'tuesday'), array('水', 'wednesday'),
array('木', 'thursday'), array('金', 'friday'),
array('土', 'saturday'));
# カレンダーの左側に表示させる曜日を設定します。
$weekdayBase = 0; // 0:日曜~6:土曜
# カレンダーに表示する年月を取得します。
// デフォルトの年月を設定
$year = (int) date('Y');
$month = (int) date('n');
// GETパラメータが指定されている場合は値を検証してから表示年月を取得
if (isset($_GET['year_month'])) {
$yyyymm = trim($_GET['year_month']);
// YYYYMM形式であれば年月を取得
if (preg_match('/^([12]\d{3})(1[012]|0[1-9])$/', $yyyymm, $match)) {
$year = (int) $match[1];
$month = (int) $match[2];
}
}
# カレンダーデータを生成します。
$calendar = new Calendar_Month_Weekdays($year, $month, $weekdayBase);
$calendar->build();
# カレンダーの曜日部分を表示します。
$thisMonth = $calendar->thisMonth(TRUE); //今月
$prevMonth = $calendar->prevMonth(TRUE); //先月
$nextMonth = $calendar->nextMonth(TRUE); //来月
$prevMonthUrl = '?year_month=' . date('Ym', $prevMonth);
$nextMonthUrl = '?year_month=' . date('Ym', $nextMonth);
$thisMonthText = date('Y/m', $thisMonth);
?>
<table border="1">
<thead>
<tr>
<td><a href="<?php echo $prevMonthUrl;?>"><<</a></td>
<th colspan="5"><?php echo $thisMonthText;?></th>
<td><a href="<?php echo $nextMonthUrl;?>">>></a></td>
</tr>
<tr>
<?php
for ($i = 0; $i < 7; $i++) {
$weekday = ($weekdayBase + $i) % 7;
$weekdayText = $weekdayDefines[$weekday][0];
$weekdayClass = $weekdayDefines[$weekday][1];
echo '<th class="' . $weekdayClass . '">', $weekdayText, '</th>';
}
?>
</tr>
</thead>
<tbody>
<?php
# カレンダーの日付部分を表示します。
$weekday = 0;
while ($day = $calendar->fetch()) {
if ($day->isFirst()) {
echo '<tr>';
}
$weekdayClass = $weekdayDefines[$weekday][1];
if ($day->isEmpty()) {
$dayText = ' ';
} else {
$dayText = $day->thisDay();
}
echo '<td class="' . $weekdayClass . '">', $dayText, '</td>';
if ($day->isLast()) {
echo '</tr>';
$weekday = 0;
} else {
$weekday++;
}
}
?>
</tr>
<tbody>
</table>
</body>
</html>
この件に関する正誤情報をどうするかは、現在、検討中です。
(2010/03/03) 正誤情報 が更新されました。


Trackback URL