時區設置 (必做第一步)
<?php
// php.ini 永久生效
date.timezone = Asia/Shanghai
// 運行時動態設置
date_default_timezone_set('Asia/Shanghai');
// 或
ini_set('date.timezone', 'Asia/Shanghai');
支持時區列表:PHP 官方文檔
date() 格式化字符完整速查表
| 類別 | 字符 | 說明 | 示例 |
| 日 | d | 月份第幾天,2位補零 | 01-31 |
| j | 月份第幾天,不補零 | 1-31 |
| S | 英文序數後綴 | st, nd, rd, th |
| z | 年份第幾天 | 0-365 |
| 周 | l | 完整星期名 | Sunday-Saturday |
| D | 3字母縮寫 | Mon-Sun |
| N | ISO-8601 數字周幾 | 1(一)-7(日) |
| w | 數字周幾 | 0(日)-6(六) |
| W | 年份第幾周 | 42 |
| 月 | F | 完整月份名 | January-December |
| m | 2位數字月份 | 01-12 |
| M | 3字母縮寫 | Jan-Dec |
| n | 數字月份 | 1-12 |
| t | 當月天數 | 28-31 |
| 年 | L | 是否閏年 | 1/0 |
| o | ISO-8601 年份 | 1999/2003 |
| Y | 4位年份 | 2024 |
| y | 2位年份 | 24 |
| 時間 | a | am/pm 小寫 | am |
| A | AM/PM 大寫 | PM |
| B | Swatch Beat | 000-999 |
| g | 12小時制不補零 | 1-12 |
| G | 24小時制不補零 | 0-23 |
| h | 12小時制補零 | 01-12 |
| H | 24小時制補零 | 00-23 |
| i | 分鐘補零 | 00-59 |
| s | 秒補零 | 00-59 |
| 時區 | e | 時區標識 | UTC, Asia/Shanghai |
| I | 是否夏令時 | 1/0 |
| T | 時區縮寫 | CST, EST |
| Z | 時區偏移秒數 | -43200~43200 |
| 完整格式 | c | ISO 8601 | 2024-01-15T14:30:00+08:00 |
| r | RFC 822 | Mon, 15 Jan 2024 14:30:00 +0800 |
| U | Unix 時間戳 | 1705309800 |
時間戳獲取三大函數
// 1. time() - 當前時間戳
$now = time(); // 等同 date('U')
// 2. mktime() - 指定日期時間生成時間戳
$ts = mktime(14, 30, 0, 1, 15, 2024); // 2024-01-15 14:30:00
// 參數順序:時、分、秒、月、日、年、is_dst(已棄用)
// 3. strtotime() - 英文自然語言解析 (最強大)
strtotime('now'); // 當前
strtotime('2024-01-15'); // 指定日期
strtotime('+1 day'); // 明天
strtotime('+1 week 2 days 4 hours'); // 復雜相對時間
strtotime('next Thursday'); // 下個周四
strtotime('last Monday'); // 上個周一
strtotime('first day of this month');// 本月1號
strtotime('last day of next month'); // 下月最後一天
常用計算實例
1. 計算年齡
$birth = mktime(0,0,0, 1, 1, 1990);
$age = floor((time() - $birth) / (365.25*24*3600)); // 考慮閏年
2. 日期加減 (推薦 strtotime)
$tomorrow = date('Y-m-d', strtotime('+1 day'));
$nextMon = date('Y-m-d', strtotime('next Monday'));
$monthEnd = date('Y-m-d', strtotime('last day of this month'));
3. 獲取日期各組件 (getdate)
$info = getdate(); // 可傳時間戳
// 返回關鍵鍵:seconds, minutes, hours, mday, wday, mon, year, yday, weekday, month, 0(時間戳)
4. 兩日期差天數 (DateTime 現代寫法 PHP 5.3+)
$d1 = new DateTime('2024-01-01');
$d2 = new DateTime('2024-12-31');
$diff = $d1->diff($d2);
echo $diff->days; // 365
echo $diff->format('%a 天 %h 小時 %i 分鐘');
MySQL 日期時間字段互轉
| 場景 | PHP → MySQL | MySQL → PHP |
| DATETIME | date('Y-m-d H:i:s', $ts) | strtotime($row['dt']) |
| TIMESTAMP | date('Y-m-d H:i:s', $ts) | strtotime($row['ts']) |
| DATE | date('Y-m-d', $ts) | strtotime($row['dt']) |
| INT(11) 存時間戳 | $ts | $row['ts'] (直接用) |
最佳實踐清單
- 入口文件統一
date_default_timezone_set('Asia/Shanghai');。
2. 業務代碼優先使用 DateTime / DateTimeImmutable 物件,避免 2038 年問題 (32位系統 time_t 溢出)。
3. 數據庫存儲統一用 DATETIME 或 TIMESTAMP,應用層轉換集中在 Repository/Mapper 層。
4. 定時任務/排程務必用 UTC 存儲,顯示時再按用戶時區轉換。
5. 單元測試覆蓋閏年、夏令時切換、月末跨月等邊界。