32 位元系統的有號整數範圍為 -2,147,483,648 ~ 2,147,483,647,對應的 Unix 時間戳上限為 2038 年 1 月 19 日 03:14:07 UTC(知名的 Y2K38 問題)。PHP 在 32 位元環境下,time()、strtotime()、date() 等函式均受限於此。
PHP 5.2+ 內建的 DateTime 類別使用 64 位元整數內部儲存,**不受 32 位元限制**,可處理極大範圍日期(約 ±2920 億年)。
<?php
// 建立 2090 年日期物件
$date = new DateTime('2090-10-01');
echo $date->format('Y-m-d H:i:s'); // 2090-10-01 00:00:00
// 從時間戳建立(支援超大整數字串)
$dt = DateTime::createFromFormat('U', '4102444800'); // 2099-12-31
echo $dt->format('Y-m-d');
// 日期運算
$dt = new DateTime('2038-01-19');
$dt->modify('+1 day');
echo $dt->format('Y-m-d'); // 2038-01-20 (正常跨越 2038 年界限)
?>
| 傳統函式 (受限) | DateTime 替代方案 |
|---|---|
time() | (new DateTime())->getTimestamp() 或 (new DateTime())->format('U') |
date('Y-m-d', $ts) | (new DateTime('@' . $ts))->format('Y-m-d') |
strtotime('+1 month') | (new DateTime())->modify('+1 month') |
mktime() | new DateTime() 後用 setDate()、setTime() |
getdate() | $dt->format('Y') 等格式化方法 |
<?php
// 明確設定時區(避免伺服器預設時區導致偏差)
date_default_timezone_set('Asia/Taipei');
// 或在 DateTime 建構子指定
$dt = new DateTime('2090-10-01', new DateTimeZone('Asia/Taipei'));
// 輸出指定時區時間
echo $dt->format('Y-m-d H:i:s T'); // 2090-10-01 00:00:00 CST
?>
DATETIME (1000-9999)、TIMESTAMP (1970-2038) —— **請改用 DATETIME**TIMESTAMP WITH TIME ZONE 範圍極大,無 2038 問題date(、strtotime(、time(、mktime(、getdate(DateTime 物件導向寫法TIMESTAMP,改為 DATETIME2090-10-01T00:00:00+08:00)而非整數時間戳採用 DateTime 不僅解決 Y2K38,更提供物件導向、鏈式呼叫、時區感知等現代功能,是 PHP 日期時間處理的標準選擇。