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

PHP 操作 MSSQL 日期時間格式轉換完全指南

     編輯:PHP 綜合知識

核心方案:SQL 層面用 CONVERT 格式化

在 SQL 查詢中直接用 `CONVERT` 將 `datetime`/`smalldatetime`/`date`/`datetime2` 轉為指定格式字符串,避免 PHP 層二次處理,效率最高。

CONVERT 風格代碼速查表 (常用)

代碼輸出格式示例說明
1202024-12-25 14:30:00ODBC 標準 (yyyy-mm-dd hh:mi:ss) **最推薦**
1212024-12-25 14:30:00.000含毫秒 (yyyy-mm-dd hh:mi:ss.mmm)
1262024-12-25T14:30:00.000ISO 8601 (含毫秒,適合 JSON/API)
11220241225純數字日期 (yyyymmdd)
232024-12-25ISO 日期 (yyyy-mm-dd)
10814:30:00僅時間 (hh:mi:ss)
109Dec 25 2024 2:30PM英文月份+12小時制
11012-25-2024美式 mm-dd-yyyy
1112024/12/25yyyy/mm/dd
202024-12-25 14:30:00同 120 (舊版別名)
212024-12-25 14:30:00.000同 121 (舊版別名)

完整列表請參考 Microsoft 官方文檔,以上覆蓋 95% 業務場景。

實戰 SQL 示例

-- 1. 標準日期時間 (最常用)
SELECT CONVERT(varchar, CreatedAt, 120) AS CreatedAtStr FROM Orders;

-- 2. 僅日期 (報表分組)
SELECT CONVERT(varchar, CreatedAt, 23) AS DateOnly, COUNT(*) FROM Orders GROUP BY CONVERT(varchar, CreatedAt, 23);

-- 3. API 返回 ISO 8601 (前端直接 new Date())
SELECT CONVERT(varchar, UpdatedAt, 126) AS UpdatedAtISO FROM Products;

-- 4. 自定義格式 (SQL Server 2012+ FORMAT 函數,更靈活但較慢)
SELECT FORMAT(CreatedAt, 'yyyy年MM月dd日 HH:mm', 'zh-TW') AS CustomFormat FROM Logs;

PHP 端處理建議

1. 直接使用資料庫返回的格式化字符串

$stmt = $pdo->query("SELECT CONVERT(varchar, CreatedAt, 120) AS CreatedAt FROM Orders");
while ($row = $stmt->fetch()) {
    echo $row['CreatedAt']; // 直接輸出 '2024-12-25 14:30:00'
}

2. 若資料庫返回原始 datetime 對象(PDO::ATTR_STRINGIFY_FETCHES = false)

$stmt = $pdo->query("SELECT CreatedAt FROM Orders");
$stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($row = $stmt->fetch()) {
    // $row['CreatedAt'] 是 DateTime 對象 (PDO SQLSRV/ODBC 驅動行為不一,建議測試)
    if ($row['CreatedAt'] instanceof DateTime) {
        echo $row['CreatedAt']->format('Y-m-d H:i:s');
    } else {
        // 某些驅動返回字符串
        echo $row['CreatedAt'];
    }
}

3. PHP 端格式化(不推薦,除非無法改 SQL)

$raw = 'Dec 25 2024 2:30PM'; // 風格 109
$ts = strtotime($raw);
echo date('Y-m-d H:i:s', $ts); // 2024-12-25 14:30:00

// 或用 DateTime
$dt = DateTime::createFromFormat('M d Y h:iA', $raw);
echo $dt->format('Y-m-d H:i:s');

驅動差異注意事項

驅動返回類型建議
sqlsrv (Microsoft 官方)DateTime 對象直接 `->format()`,最優
pdo_sqlsrvDateTime 對象同上
odbc / pdo_odbc字符串 (視 ODBC 設置)SQL 用 CONVERT 固定格式
mssql (已棄用 PHP 7+)字符串升級驅動
dblib (FreeTDS)字符串SQL 用 CONVERT 固定格式

時區處理關鍵點

  • MSSQL `datetime` **不存儲時區**,視為伺服器本地時間。
  • PHP `DateTime` 預設使用 `date.timezone` (php.ini) 或 `date_default_timezone_set()`。
  • **最佳實踐**:資料庫層統一存 UTC,或應用層約定「所有時間均為 Asia/Taipei」,雙端設置一致時區,避免轉換。

常見問題 FAQ

Q: 為什麼插入時間比 PHP time() 少 8 小時?
A: 資料庫伺服器時區與 PHP 時區不一致。檢查 `SELECT SYSDATETIMEOFFSET()` 及 PHP `date_default_timezone_get()`。
Q: CONVERT 120 返回的字符串能否直接給 JavaScript `new Date()`?
A: 能,但更推薦風格 126 (ISO 8601),如 `2024-12-25T14:30:00.000`,瀏覽器解析最穩健。
Q: 如何在 WHERE 條件中按日期篩選?
A: `WHERE CreatedAt >= '2024-12-01' AND CreatedAt < '2025-01-01'`(利用索引),**不要**對列用 CONVERT/FORMAT,會導致掃描。

總結

  1. 首選 SQL `CONVERT(..., 120/126)` 格式化,效能好、格式穩定。
  2. 升級 sqlsrv/pdo_sqlsrv 驅動,直接獲取 `DateTime` 對象,PHP 端零成本格式化。
  3. 統一時區約定,避免跨層轉換 Bug。
  4. WHERE 條件勿對列使用函數,保持 SARGable 利用索引。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved