首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP date() 與 gmdate() 差異深度解析:時區處理最佳實踐

     編輯:PHP 相關知識

核心差異一覽

函數說明受 date.timezone 影響典型用途
date()格式化本地時間是顯示給使用者看的時間
gmdate()格式化 GMT/UTC 時間否儲存、API 傳輸、跨時區計算

實測差異(以 UTC+8 環境為例)

// 假設當前 UTC 時間 2007-03-14 04:15:27
date_default_timezone_set('Asia/Taipei'); // UTC+8

echo date('Y-m-d H:i:s');   // 2007-03-14 12:15:27 (本地時間)
echo gmdate('Y-m-d H:i:s'); // 2007-03-14 04:15:27 (UTC 時間)

關鍵發現:在 Windows + PHP 環境下,date() 預設也會回傳 UTC,導致跨平台行為不一致。

跨平台相容寫法:統一使用 gmdate + 手動偏移

// 統一取得「使用者時區」的時間
$userOffset = 8 * 3600; // 秒數,例如 +8 區
echo gmdate('Y-m-d H:i:s', time() + $userOffset);
// 輸出:2007-03-14 12:15:27 (在任何作業系統皆一致)

優點:資料庫只存 time()(UTC 時間戳),前端依使用者設定時區動態換算,完美支援全球化應用。

修改 PHP 預設時區的兩種方式

1. 修改 php.ini(需伺服器權限)

date.timezone = "Asia/Taipei"
// 或 "Asia/Shanghai", "PRC", "Etc/GMT-8"

2. 程式碼動態設定(共享主機適用,PHP 5.1+)

date_default_timezone_set('Asia/Taipei'); // 推薦
// date_default_timezone_set('PRC');
echo date('Y-m-d H:i:s'); // 直接輸出正確本地時間

深度驗證:time()、date()、gmdate() 三者關係

<?php
// 測試環境:預設 UTC
date_default_timezone_set('Etc/GMT');
echo "time(): " . time() . "\n";           // 1276257131 (UTC 時間戳)
echo "date(): " . date('Y-m-d H:i:s') . "\n";   // 2010-06-11 11:52:11 (UTC)
echo "gmdate(): " . gmdate('Y-m-d H:i:s') . "\n"; // 2010-06-11 11:52:11 (UTC)

echo "\n---\n";
// 切換到 PRC (UTC+8)
date_default_timezone_set('PRC');
echo "time(): " . time() . "\n";           // 1276257131 (不變!)
echo "date(): " . date('Y-m-d H:i:s') . "\n";   // 2010-06-11 19:52:11 (本地+8)
echo "gmdate(): " . gmdate('Y-m-d H:i:s') . "\n"; // 2010-06-11 11:52:11 (仍為UTC)

結論總結

  • time():永遠回傳 UTC 時間戳,不受時區影響。
  • date():將 UTC 時間戳轉為當前設定時區的格式化字串。
  • gmdate():將 UTC 時間戳轉為UTC格式化字串,不受時區影響。

strtotime() 時區行為補充

<?php
date_default_timezone_set('Etc/GMT');
echo strtotime('1970-01-01 08:00:00'); // 28800 (把輸入視為 UTC+8,換算回 UTC)

date_default_timezone_set('PRC');
echo strtotime('1970-01-01 08:00:00'); // 0 (輸入視為本地 PRC,即 UTC+8,換算回 UTC 為 0)

strtotime() 會依當前 PHP 時區設定解析字串,再轉為 UTC 時間戳。

最佳實踐建議

  1. 資料庫統一存儲 UTC:使用 TIMESTAMP 或 BIGINT 存 time()。
  2. 程式碼啟動時設定時區:date_default_timezone_set('Asia/Taipei')。
  3. 顯示層才做時區轉換:前端 JS 拿 UTC 時間戳,按使用者瀏覽器時區渲染。
  4. 避免手動加減秒數:改用 DateTime + DateTimeZone 物件導向做法(PHP 5.2+)。

現代化寫法範例(PHP 7+)

$utc   = new DateTime('now', new DateTimeZone('UTC'));
$taipei = clone $utc;
$taipei->setTimezone(new DateTimeZone('Asia/Taipei'));

echo "UTC:      " . $utc->format('Y-m-d H:i:s') . "\n";
echo "Taipei:   " . $taipei->format('Y-m-d H:i:s') . "\n";

// 使用者自訂時區
$userTz = new DateTimeZone('America/New_York');
$userTime = clone $utc;
$userTime->setTimezone($userTz);
echo "New York: " . $userTime->format('Y-m-d H:i:s');
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved