date() 是 PHP 最常用的日期格式化函數,支援豐富的格式字元。本文整理完整格式字元表、時間戳操作、常用進階函數 (strtotime, DateTime, microtime 等)、時區處理最佳實踐,並提供可直接使用的格式化速查表。
date() 格式字元完整速查表
| 字元 | 說明 | 範例輸出 |
| 年 | | |
Y | 4 位數年份 | 2024 |
y | 2 位數年份 | 24 |
| 月 | | |
m | 數字月份,前導零 | 01-12 |
n | 數字月份,無前導零 | 1-12 |
F | 月份完整英文名 | January |
M | 月份縮寫 (3 字母) | Jan |
| 日 | | |
d | 月份中的第幾天,前導零 | 01-31 |
j | 月份中的第幾天,無前導零 | 1-31 |
S | 日期序數後綴 | st, nd, rd, th |
| 時間 (12 小時制) | | |
g | 小時,無前導零 | 1-12 |
h | 小時,前導零 | 01-12 |
i | 分鐘,前導零 | 00-59 |
s | 秒,前導零 | 00-59 |
a | am/pm 小寫 | am |
A | AM/PM 大寫 | PM |
| 時間 (24 小時制) | | |
G | 小時,無前導零 | 0-23 |
H | 小時,前導零 | 00-23 |
| 星期 | | |
l | 星期完整英文名 | Monday |
D | 星期縮寫 (3 字母) | Mon |
w | 星期數字 (0=Sunday) | 0-6 |
W | 年份中的第幾週 (ISO-8601) | 01-53 |
| 其他 | | |
z | 年份中的第幾天 (0 起) | 0-365 |
t | 當月總天數 | 28-31 |
L | 是否閏年 | 1/0 |
I | 是否夏令時間 | 1/0 |
U | Unix 時間戳 | 1705315200 |
c | ISO 8601 格式 | 2024-01-15T14:30:00+08:00 |
r | RFC 2822 格式 | Mon, 15 Jan 2024 14:30:00 +0800 |
T | 伺服器時區縮寫 | CST |
常用格式組合範例
<?php
$now = time();
echo date('Y-m-d', $now); // 2024-01-15
echo date('Y/m/d H:i:s', $now); // 2024/01/15 14:30:00
echo date('Y年m月d日 H時i分', $now); // 2024年01月15日 14時30分
echo date('l, F jS, Y', $now); // Monday, January 15th, 2024
echo date('D, d M Y H:i:s T', $now); // Mon, 15 Jan 2024 14:30:00 CST
echo date('c', $now); // 2024-01-15T14:30:00+08:00 (ISO 8601)
echo date('r', $now); // Mon, 15 Jan 2024 14:30:00 +0800 (RFC 2822)
?>
時間戳操作
mktime() / gmmktime() - 建立時間戳
<?php
// 本地時間建立
$ts = mktime(14, 30, 0, 1, 15, 2024); // 2024-01-15 14:30:00 (本地時區)
echo date('Y-m-d H:i:s', $ts);
// UTC 時間建立
$utcTs = gmmktime(6, 30, 0, 1, 15, 2024); // 2024-01-15 06:30:00 UTC
echo gmdate('Y-m-d H:i:s', $utcTs);
// 明天這個時間
$tomorrow = mktime(date('H'), date('i'), date('s'), date('m'), date('d')+1, date('Y'));
?>
strtotime() - 自然語言解析
<?php
echo date('Y-m-d', strtotime('tomorrow')); // 明天
echo date('Y-m-d', strtotime('next Monday')); // 下週一
echo date('Y-m-d', strtotime('+1 week 3 days')); // 1 週又 3 天後
echo date('Y-m-d', strtotime('first day of next month')); // 下月 1 號
echo date('Y-m-d', strtotime('last day of February 2024')); // 2024-02-29 (閏年)
?>
getdate() - 時間戳轉關聯陣列
<?php
$arr = getdate(); // 當前時間
// 或 $arr = getdate($timestamp);
echo "Date: {$arr['mday']} {$arr['month']} {$arr['year']}";
echo "Time: {$arr['hours']}:{$arr['minutes']}:{$arr['seconds']}";
// 可用鍵: seconds, minutes, hours, mday, wday, mon, year, yday, weekday, month, 0 (時間戳)
?>
進階日期時間函數
| 函數 | 用途 | 關鍵特性 |
checkdate(m,d,Y) | 驗證日期合法性 | 回傳 bool,月/日/年順序 |
strftime(format, ts) | 當地化格式化 (依 setlocale) | 支援 %B (月名), %A (星期名) 等 |
microtime(true) | 微秒級時間戳 (float) | 效能測量、高精度時間 |
date_default_timezone_set() | 設定腳本預設時區 | 影響所有日期函數,**必須在 php.ini 或腳本開頭設定** |
DateTime 類別 | 物件導向日期時間操作 | 時區轉換、修改、差值、格式化、不可變版 DateTimeImmutable |
DateTime 現代用法 (PHP 5.2+,推薦)
<?php
// 建立
$dt = new DateTime('now', new DateTimeZone('Asia/Taipei'));
$dt = new DateTime('2024-01-15 14:30:00');
$dt = DateTime::createFromFormat('Y/m/d H:i', '2024/01/15 14:30');
// 格式化
echo $dt->format('Y-m-d H:i:s');
echo $dt->format(DateTime::ATOM); // 常數
// 時區轉換 (核心優勢)
$utc = clone $dt;
$utc->setTimezone(new DateTimeZone('UTC'));
echo $utc->format('Y-m-d H:i:s');
// 日期運算
$dt->modify('+1 week');
$dt->modify('first day of this month');
$dt->add(new DateInterval('P1M')); // 1 個月
$dt->sub(new DateInterval('P3D')); // 3 天
// 差值
$diff = $dt1->diff($dt2);
echo $diff->format('%a 天 %h 小時 %i 分鐘');
// 比較
if ($dt1 > $dt2) { ... }
if ($dt1 == $dt2) { ... }
// 不可變版本 (PHP 5.5+,推薦避免副作用)
$immutable = new DateTimeImmutable('now');
$nextWeek = $immutable->modify('+1 week'); // 回傳新物件,原物件不變
?>
時區處理最佳實踐 (必讀)
- php.ini 設定:
date.timezone = "Asia/Taipei" (或系統時區)
- 儲存/運算用 UTC:資料庫存
TIMESTAMP (UTC) 或 BIGINT 時間戳
- 顯示時轉換:用
DateTime::setTimezone() 轉換為使用者時區
- 避免手動秒數偏移:
time() + 3600*8 夏令時間會錯
常見格式化需求速查
| 需求 | 代碼 |
| 今天 00:00:00 時間戳 | strtotime('today') 或 (new DateTime())->setTime(0,0)->getTimestamp() |
| 本月第一天 | date('Y-m-01') 或 (new DateTime())->modify('first day of this month') |
| 本月最後一天 | date('Y-m-t') 或 (new DateTime())->modify('last day of this month') |
| 兩日期相差天數 | (strtotime($date2) - strtotime($date1)) / 86400 或 $dt1->diff($dt2)->days |
| 年齡計算 | (new DateTime($birth))->diff(new DateTime())->y |
| Unix 時間戳轉日期 | date('Y-m-d H:i:s', $timestamp) |
| 毫秒時間戳 | microtime(true) * 1000 (float) 或 (int)(microtime(true) * 1000) |