核心組合模式
<?php
// 任意可解析日期字符串 → Unix 時間戳 → 格式化輸出
$formatted = date('Y-m-d', strtotime($rawDateTime));
strtotime() 解析能力詳解
| 輸入格式 | 示例 | 說明 |
| 標準日期 | '2024-01-15' | ISO 8601 |
| 美式日期 | '01/15/2024' | 月/日/年 |
| 英文描述 | 'next Monday' | 相對時間,極其強大 |
| 相對時間 | '+ 3 days', '- 2 weeks' | 相對當前或基準時間 |
| 時間戳字符串 | '@1705315200' | @ 前綴表示 Unix 時間戳 |
| 組合描述 | 'first day of next month' | 複雜日曆計算 |
date() 格式化字符完整參考
| 字符 | 含義 | 示例 |
Y | 四位數年份 | 2024 |
y | 兩位數年份 | 24 |
m | 數字月份(補零) | 01-12 |
n | 數字月份(不補零) | 1-12 |
d | 日期(補零) | 01-31 |
j | 日期(不補零) | 1-31 |
H | 24小時制(補零) | 00-23 |
h | 12小時制(補零) | 01-12 |
i | 分鐘(補零) | 00-59 |
s | 秒(補零) | 00-59 |
w | 星期(0=周日) | 0-6 |
D | 星期縮寫 | Mon-Sun |
l | 星期全稱 | Monday-Sunday |
t | 當月天數 | 28-31 |
z | 當年天數 | 0-365 |
W | ISO 週數 | 01-53 |
c | ISO 8601 完整 | 2024-01-15T10:30:00+08:00 |
r | RFC 2822 | Mon, 15 Jan 2024 10:30:00 +0800 |
常用格式化模板
<?php
$ts = time(); // 當前時間戳
// 日期類
date('Y-m-d', $ts); // 2024-01-15
date('Y年m月d日', $ts); // 2024年01月15日
date('Y/m/d', $ts); // 2024/01/15
// 日期時間類
date('Y-m-d H:i:s', $ts); // 2024-01-15 14:30:05
date('Y-m-d\TH:i:sP', $ts); // 2024-01-15T14:30:05+08:00 (ISO 8601)
// 時間類
date('H:i:s', $ts); // 14:30:05
date('h:i A', $ts); // 02:30 PM
// 中文友好
date('Y年n月j日 l H:i', $ts); // 2024年1月15日 Monday 14:30
strtotime() 進階用法
<?php
// 指定基準時間(第二參數)
strtotime('+ 1 day', strtotime('2024-01-15')); // 2024-01-16 00:00:00
// 複雜相對時間
strtotime('first day of this month'); // 本月 1 號 00:00:00
strtotime('last day of next month'); // 下月最後一天 23:59:59
strtotime('third wednesday of july 2024'); // 2024 年 7 月第三個周三
// 解析失敗返回 false(PHP 5.1+)
$result = strtotime('invalid date');
if ($result === false) {
// 處理錯誤
}
// 32 位系統時間戳範圍限制(1901-2038)
// 64 位系統無此限制,支援億年範圍
現代替代方案:DateTime 類(推薦 PHP 5.2+)
<?php
// 1. 創建
$dt = new DateTime('2024-01-15 14:30:00');
$dt = new DateTime('@1705315200'); // 從時間戳
$dt = DateTime::createFromFormat('Y-m-d', '2024-01-15'); // 指定格式解析
// 2. 格式化
echo $dt->format('Y-m-d H:i:s');
// 3. 修改(鏈式調用)
$dt->modify('+ 3 days')->modify('first day of this month');
// 4. 時區處理
$dt->setTimezone(new DateTimeZone('America/New_York'));
// 5. 計算差值
$diff = $dt1->diff($dt2);
echo $diff->format('%a 天 %h 小時 %i 分鐘');
// 6. 迭代器
$period = new DatePeriod(
new DateTime('2024-01-01'),
new DateInterval('P1D'),
10
);
foreach ($period as $day) {
echo $day->format('Y-m-d') . "\n";
}
時區最佳實踐
<?php
// 1. 腳本級設置(入口文件最早處)
date_default_timezone_set('Asia/Shanghai'); // 或 UTC
// 2. php.ini 全局設置
// date.timezone = Asia/Shanghai
// 3. DateTime 顯式時區(推薦)
$dt = new DateTime('now', new DateTimeZone('Asia/Shanghai'));
常見陷阱避坑指南
| 陷阱 | 錯誤示例 | 正確做法 |
| m/d/Y vs d/m/Y 歧義 | strtotime('01/02/2024') → 1月2日(美式) | 用 ISO 格式 '2024-01-02' 或 DateTime::createFromFormat |
| 月份溢出 | date('Y-m-d', strtotime('2024-01-31 +1 month')) → 2024-03-03 | 用 'first day of next month' 或 DateTime modify |
| 夏令時跳躍 | 相對時間計算跨 DST 邊界 | 用 DateTime + 時區,避免手動加減秒數 |
| 32位系統 2038 問題 | strtotime('2040-01-01') 返回 false | 升級 64 位 PHP 或用 DateTime |
| 時區未設置警告 | E_WARNING: date()... timezone settings | 入口文件 date_default_timezone_set() |
效能建議
- 高頻調用:
date() + time() 比 DateTime 快 3-5 倍
- 複雜業務邏輯:用
DateTime 可讀性強、不易出錯
- 批量格式化:預編譯格式字符串,避免重複解析
掌握 strtotime() 的解析威力與 date() 的格式化靈活性,配合現代 DateTime 類,讓 PHP 日期時間處理得心應手!