PHP 在 32 位元系統上受限於有號整數範圍,時間戳有效區間為 1901-12-13 20:45:54 至 2038-01-19 03:14:07(GMT)。超出此範圍的日期(如 2050 年、2100 年)會導致 date()、strtotime() 等函式回傳錯誤或 false。64 位元系統不受此限制,但在 Windows 上 PHP 5.1 之前同樣受限於 1970-2038 區間。
// 32 位元環境下
echo date('Y-m-d', strtotime('2050-01-01')); // 輸出 1970-01-01 或 false
var_dump(strtotime('2100-12-31')); // bool(false)
DateTime 類別(PHP 5.2+)內部使用 64 位元整數或浮點數儲存時間,不受 32 位元限制,可處理極大範圍日期(約 ±2920 億年)。
$date = new DateTime('2090-10-01');
echo $date->format('Y-m-d H:i:s'); // 2090-10-01 00:00:00
// 指定時區
$dt = new DateTime('2050-12-31 23:59:59', new DateTimeZone('Asia/Taipei'));
echo $dt->format('Y-m-d H:i:s P');
$dt = new DateTime('@2147483647'); // 2038-01-19 03:14:07
$dt = new DateTime('@4102444800'); // 2100-01-01 00:00:00 (需 64 位元或 DateTime)
$start = new DateTime('2050-01-01');
$end = new DateTime('2060-01-01');
$interval = $start->diff($end);
echo $interval->format('%y 年 %m 月 %d 天'); // 10 年 0 月 0 天
// 比較
if ($start < $end) { echo 'start 在 end 之前'; }
| 方案 | 適用版本 | 優點 | 缺點 |
|---|---|---|---|
| DateTime 類別 | PHP 5.2+ | 物件導向、支援時區、運算豐富、跨平台 | 舊代碼遷移成本稍高 |
| 64 位元 PHP + 64 位元 OS | PHP 5.1+ | 原生函式直接可用 | 需更換伺服器環境,Windows 早期版本仍有限制 |
自訂函式庫(如 php_time) | 所有版本 | 不改動環境 | 維護成本高、效能較差 |
date(、strtotime(、mktime(、time( 呼叫處DATETIME/TIMESTAMP 欄位讀寫邏輯DATETIME 或 BIGINT 儲存毫秒級時間戳2024-12-31T23:59:59+08:00,避免整數截斷date_default_timezone_set('Asia/Taipei') 或在 php.ini 設定隨著 2038 年臨近,提前遷移至 DateTime 是最穩妥的策略。即使目前運行在 64 位元環境,統一使用物件導向時間處理也能提升代碼可維護性與跨平台一致性。