類別功能
Calendar 類別封裝月曆產生邏輯:指定時間戳初始化、判斷閏年、計算月初星期、產生 HTML 表格、今日紅字加粗、上/下月導航連結佔位。適合嵌入後台管理、預約系統、部落格側邊欄。
完整類別程式碼
'31','2'=>'28','3'=>'31','4'=>'30','5'=>'31','6'=>'30',
'7'=>'31','8'=>'31','9'=>'30','10'=>'31','11'=>'30','12'=>'31'
);
var $Y, $M, $D;
function set($time) {
$this->T = getdate($time);
$this->Y = $this->T['year'];
$this->M = $this->T['mon'];
$this->D = date('d', $time);
}
// 閏年判斷:400 整除 或 4 整除且非 100 整除
function isLeapYear() {
return ($this->Y % 400 == 0 || ($this->Y % 4 == 0 && $this->Y % 100 != 0)) ? 1 : 0;
}
// 取得該月 1 號是星期幾 (0=日, 6=六)
function firstWeekday() {
$time = mktime(0, 0, 0, $this->M, 1, $this->Y);
return getdate($time)['wday'];
}
function render() {
$isLeap = $this->isLeapYear();
$this->datesOfMonth[2] = $isLeap ? 29 : 28;
$html = "\n";
// 標題列:上月、年月、下月
$html .= "| « 上月 | ";
$html .= "{$this->Y}年 {$this->M}月 | ";
$html .= "下月 » |
\n";
// 星期標題
$html .= "";
foreach (array('日','一','二','三','四','五','六') as $w) {
$html .= "| $w | ";
}
$html .= "
\n";
// 前導空白
$first = $this->firstWeekday();
for ($i = 0; $i < $first; $i++) $html .= " | ";
// 日期格
$count = $this->datesOfMonth[$this->M] + $first;
for ($i = 1; $i <= $this->datesOfMonth[$this->M]; $i++) {
$style = ($i == $this->D) ? " style='color:red; font-weight:bold; background:#fffacd;'" : " style='padding:3px;'";
$html .= "$i | ";
// 每週換行
if ((($i + $first) % 7 == 0) && $i < $count) {
$html .= "
\n";
}
}
// 尾部空白
$remain = 7 - ($count % 7);
if ($remain < 7) {
for ($i = 0; $i < $remain; $i++) $html .= " | ";
}
$html .= "
\n
\n";
return $html;
}
}
// 使用範例
$calendar = new Calendar();
$calendar->set(time()); // 當前時間
echo $calendar->render();
輸出範例(HTML 結構)
擴充功能建議
- 導航實作:上/下月連結帶入
?ym=2024-01,後端 strtotime("$ym first day") 初始化
- 農曆/節氣:整合農曆轉換庫(如
chinese-calendar),顯示節氣、傳統節日
- 事件標記:資料庫查詢該月事件,日期格加入
data-events、點擊彈窗
- 多月顯示:支援
render(3) 連續輸出 3 月
- 無障礙:
<table> 加 role="grid"、aria-label、鍵盤導航支援
- 樣式分離:移除 inline style,改用 CSS 類別,支援主題切換
DateTime 物件導向重構(PHP 5.3+)
class Calendar {
private DateTime $date;
private array $monthDays = [31,28,31,30,31,30,31,31,30,31,30,31];
public function __construct(DateTime $date = null) {
$this->date = $date ?? new DateTime();
}
public function isLeapYear(): bool {
$y = (int)$this->date->format('Y');
return $y % 400 === 0 || ($y % 4 === 0 && $y % 100 !== 0);
}
public function render(): string { /* ... 邏輯同前,使用 $this->date->format('Y/m/d') 等 ... */ }
}