日期時間處理是 Web 開發中高頻需求。PHP 提供豐富的函數支援 Unix 時間戳轉換、日期格式化、時區設定、日期運算與驗證,本文系統整理並附上日曆生成實戰範例。
Unix 時間戳(Timestamp)表示從 1970-01-01 00:00:00 UTC 至今的秒數。它是跨平台、跨資料庫儲存與交換日期時間的標準格式,解決不同資料庫時間型別不相容問題。
strtotime() 可解析多種英文日期字串格式:
<?php
echo strtotime('2009-03-05'); // 1236211200
echo strtotime('2009-03-05 10:24:30'); // 1236248670
echo strtotime("10 September 2000"); // 968544000
?>
mktime() 依指定時、分、秒、月、日、年建立時間戳:
int mktime([int $hour [, int $minute [, int $second [, int $month [, int $day [, int $year]]]]]])
date() 將時間戳依指定格式字串轉為可讀日期時間:
string date(string $format [, int $timestamp ])
常用格式字元對照表:
| 字元 | 說明 | 範例 |
|---|---|---|
| Y | 4位數年份 | 2024 |
| m | 月份(有前導零) | 01-12 |
| d | 月份中的第幾天(有前導零) | 01-31 |
| H | 24小時制(有前導零) | 00-23 |
| i | 分鐘(有前導零) | 00-59 |
| s | 秒數(有前導零) | 00-59 |
| w | 星期幾(數字) | 0(週日)-6(週六) |
| c | ISO 8601 格式 | 2024-01-15T10:30:00+08:00 |
| r | RFC 822 格式 | Mon, 15 Jan 2024 10:30:00 +0800 |
更多格式字元請參考 PHP 官方文件。
getdate() 回傳包含秒、分、時、日、月、年、星期、年度第幾天等鍵值的關聯陣列:
<?php
$info = getdate();
print_r($info);
/* 輸出範例:
Array (
[seconds] => 30
[minutes] => 10
[hours] => 10
[mday] => 15
[wday] => 1
[mon] => 1
[year] => 2024
[yday] => 14
[weekday] => Monday
[month] => January
[0] => 1705284630
)
*/
?>
<?php
$old = mktime(0,0,0,9,24,2008);
$new = mktime(0,0,0,10,12,2008);
$days = ($new - $old) / (24*3600);
echo $days; // 18
?>
<?php
var_dump(checkdate(12,31,2000)); // bool(true)
var_dump(checkdate(2,29,2001)); // bool(false) 非閏年
?>
PHP 預設使用 UTC 時間。使用 date_default_timezone_set() 設定本地時區:
<?php
// 中國大陸常用時區識別碼
date_default_timezone_set('Asia/Shanghai'); // 或 'Asia/Chongqing', 'PRC'
echo date('Y-m-d H:i:s'); // 輸出北京時間
?>
結合 $_GET 參數、date()、mktime() 實作可翻閱年月的 HTML 日曆:
<?php
$year = @$_GET['year'] ?: date('Y');
$month = @$_GET['month'] ?: date('n');
$day = date('j');
$wd_ar = array("日","一","二","三","四","五","六");
$wd = date('w', mktime(0,0,0,$month,1,$year)); // 當月第一天星期幾
// 年份導航連結
$y_lnk1 = $year <= 1970 ? 1970 : $year - 1;
$y_lnk2 = $year >= 2037 ? 2037 : $year + 1;
// 月份導航連結
$m_lnk1 = $month <= 1 ? 1 : $month - 1;
$m_lnk2 = $month >= 12 ? 12 : $month + 1;
echo "<table cellpadding=6 cellspacing=0 width=200 bgcolor=#eeeeee><tr align=center bgcolor=#cccccc>";
echo "<td colspan=4><a href='?year=$y_lnk1&month=$month'><</a>$year年<a href='?year=$y_lnk2&month=$month'>></a></td>";
echo "<td colspan=3><a href='?year=$year&month=$m_lnk1'><</a>$month月<a href='?year=$year&month=$m_lnk2'>></a></td></tr>";
echo "<tr align=center>";
for ($i=0; $i<7; $i++) echo "<td>$wd_ar[$i]</td> ";
echo "</tr>";
$tnum = $wd + date('t', mktime(0,0,0,$month,1,$year)); // 總格數
for ($i=0; $i<$tnum; $i++) {
$date = $i + 1 - $wd;
if ($i % 7 == 0) echo "<tr align=center>";
echo "<td>";
if ($i >= $wd) {
if ($date == $day && $month == date('n')) echo "<b>$day</b>";
else echo $date;
}
echo "</td> ";
if ($i % 7 == 6) echo "</tr> ";
}
echo "</table>";
?>