PHP 內建支援完整的 IANA 時區資料庫,透過 date_default_timezone_set()、DateTimeZone 類別或 php.ini 設定時區。正確的時區處理對於跨國應用、日誌記錄、排程任務、資料庫時間戳一致性至關重要。本文提供完整時區識別符列表、設定最佳實務與常見錯誤對策。
<?php
date_default_timezone_set('Asia/Taipei'); // 台灣標準時間
// 或
date_default_timezone_set('UTC'); // 統一使用 UTC 存儲
; php.ini
date.timezone = "Asia/Taipei"
$dt = new DateTime('now', new DateTimeZone('Asia/Taipei'));
echo $dt->format('Y-m-d H:i:s T'); // 2024-01-15 14:30:00 CST
Asia/Shanghai (中國標準時間 CST, UTC+8) Asia/Taipei (台灣標準時間 CST, UTC+8) **台灣專用** Asia/Hong_Kong (香港時間 HKT, UTC+8) Asia/Tokyo (日本標準時間 JST, UTC+9) Asia/Seoul (韓國標準時間 KST, UTC+9) Asia/Singapore (新加坡時間 SGT, UTC+8) Asia/Bangkok (泰國時間 ICT, UTC+7) Asia/Jakarta (印尼西部時間 WIB, UTC+7) Asia/Kolkata (印度標準時間 IST, UTC+5:30) Asia/Dubai (海灣標準時間 GST, UTC+4) Asia/Tehran (伊朗標準時間 IRST, UTC+3:30) Asia/Jerusalem (以色列標準時間 IST, UTC+2/3 夏令時間) Asia/Riyadh (阿拉伯標準時間 AST, UTC+3) Asia/Baghdad (阿拉伯標準時間 AST, UTC+3) Asia/Karachi (巴基斯坦標準時間 PKT, UTC+5) Asia/Kathmandu (尼泊爾時間 NPT, UTC+5:45) Asia/Yangon (緬甸時間 MMT, UTC+6:30) Asia/Phnom_Penh (柬埔寨時間 ICT, UTC+7) Asia/Vientiane (寮國時間 ICT, UTC+7) Asia/Ho_Chi_Minh (越南時間 ICT, UTC+7) Asia/Kuala_Lumpur (馬來西亞時間 MYT, UTC+8) Asia/Manila (菲律賓標準時間 PST, UTC+8) Asia/Ulaanbaatar (蒙古標準時間 ULAT, UTC+8) Asia/Irkutsk (伊爾庫茨克時間 IRKT, UTC+8) Asia/Yakutsk (雅庫茨克時間 YAKT, UTC+9) Asia/Vladivostok (海參崴時間 VLAT, UTC+10) Asia/Magadan (馬加丹時間 MAGT, UTC+11) Asia/Kamchatka (堪察加時間 PETT, UTC+12)
America/New_York (東部時間 EST/EDT, UTC-5/-4) America/Chicago (中部時間 CST/CDT, UTC-6/-5) America/Denver (山區時間 MST/MDT, UTC-7/-6) America/Los_Angeles (太平洋時間 PST/PDT, UTC-8/-7) America/Anchorage (阿拉斯加時間 AKST/AKDT, UTC-9/-8) America/Adak (阿留申時間 HAST/HADT, UTC-10/-9) America/Toronto (加拿大東部) America/Vancouver (加拿大太平洋) America/Mexico_City (墨西哥中部時間) America/Sao_Paulo (巴西利亞時間 BRT/BRST, UTC-3/-2) America/Buenos_Aires (阿根廷時間 ART, UTC-3) America/Lima (秘魯時間 PET, UTC-5) America/Bogota (哥倫比亞時間 COT, UTC-5) America/Caracas (委內瑞拉時間 VET, UTC-4)
Europe/London (格林威治時間 GMT/BST, UTC+0/+1) Europe/Paris (中歐時間 CET/CEST, UTC+1/+2) Europe/Berlin (中歐時間 CET/CEST, UTC+1/+2) Europe/Rome (中歐時間 CET/CEST, UTC+1/+2) Europe/Madrid (中歐時間 CET/CEST, UTC+1/+2) Europe/Amsterdam (中歐時間 CET/CEST, UTC+1/+2) Europe/Zurich (中歐時間 CET/CEST, UTC+1/+2) Europe/Vienna (中歐時間 CET/CEST, UTC+1/+2) Europe/Warsaw (中歐時間 CET/CEST, UTC+1/+2) Europe/Moscow (莫斯科時間 MSK, UTC+3) Europe/Istanbul (土耳其時間 TRT, UTC+3) Europe/Helsinki (東歐時間 EET/EEST, UTC+2/+3) Europe/Kiev (東歐時間 EET/EEST, UTC+2/+3) Europe/Athens (東歐時間 EET/EEST, UTC+2/+3) Europe/Lisbon (西歐時間 WET/WEST, UTC+0/+1) Europe/Dublin (西歐時間 WET/WEST, UTC+0/+1)
Australia/Sydney (澳洲東部時間 AEST/AEDT, UTC+10/+11) Australia/Melbourne (澳洲東部時間 AEST/AEDT, UTC+10/+11) Australia/Brisbane (澳洲東部標準時間 AEST, UTC+10, 無夏令) Australia/Perth (澳洲西部時間 AWST, UTC+8) Australia/Adelaide (澳洲中部時間 ACST/ACDT, UTC+9:30/+10:30) Australia/Darwin (澳洲中部標準時間 ACST, UTC+9:30) Pacific/Auckland (紐西蘭標準時間 NZST/NZDT, UTC+12/+13) Pacific/Fiji (斐濟時間 FJT/FJST, UTC+12/+13) Pacific/Guam (關島時間 ChST, UTC+10) Pacific/Honolulu (夏威夷時間 HST, UTC-10)
Africa/Cairo (埃及時間 EET, UTC+2) Africa/Johannesburg (南非標準時間 SAST, UTC+2) Africa/Lagos (西非時間 WAT, UTC+1) Africa/Nairobi (東非時間 EAT, UTC+3) Antarctica/McMurdo (麥克默多站, UTC+12/13) Arctic/Longyearbyen (斯瓦爾巴群島, UTC+1/2) Atlantic/Azores (亞速爾群島, UTC-1/0) Atlantic/Reykjavik (雷克雅維克, UTC+0) Indian/Mauritius (毛里求斯時間 MUT, UTC+4) Indian/Reunion (留尼汪時間 RET, UTC+4) Pacific/Apia (薩摩亞時間, UTC+13/14) Pacific/Chatham (查塔姆群島, UTC+12:45/13:45)
<?php
$timezones = DateTimeZone::listIdentifiers();
// 依洲份分組
$byContinent = [];
foreach ($timezones as $tz) {
$parts = explode('/', $tz);
$byContinent[$parts[0]][] = $tz;
}
print_r($byContinent);
// 僅列出亞洲
$asian = DateTimeZone::listIdentifiers(DateTimeZone::ASIA);
print_r($asian);
// 搜尋包含關鍵字
$search = 'Taipei';
$found = array_filter($timezones, fn($tz) => stripos($tz, $search) !== false);
print_r($found); // ["Asia/Taipei"]
| 陷阱 | 說明 | 對策 |
|---|---|---|
| 使用縮寫 (CST, EST, PST) | 不明確:CST 可能指中國、美國中部、古巴等 | 一律使用 IANA 識別符:Asia/Shanghai, America/Chicago |
| 忽略夏令時間 (DST) | 部分時區有夏令轉換,固定偏移會導致錯誤 | 使用 IANA 時區自動處理 DST |
| 伺服器與資料庫時區不一致 | MySQL time_zone、PostgreSQL TimeZone、PHP 設定不同步 | 統一設定為 UTC,應用層轉換顯示時區 |
| 儲存本地時間而非 UTC | 跨時區查詢、排序、計算極其困難 | 資料庫儲存 UTC (TIMESTAMP/DATETIME + UTC),前端按用戶時區顯示 |
| date() vs DateTime 不一致 | date() 受 date_default_timezone_set 影響,DateTime 可獨立指定 | 新代碼優先使用 DateTime + DateTimeZone |
| 時區資料庫過舊 | PHP 內建時區資料可能非最新 (政治調整時區、DST 規則變更) | 定期更新 PHP、或安裝 pecl install timezonedb |