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

PHP 與 MySQL 日期比較完整指南:時間戳、日期型別互轉與常用查詢模式

     編輯:PHP 綜合知識

專案中常遇到「找出最近 30 天文章」、「按月統計銷售額」、「判斷某筆記錄是否為今天」等日期比較需求。本文系統整理 MySQL 與 PHP 端的日期比較方法,涵蓋 Unix 時間戳、DATE/DATETIME/TIMESTAMP 型別、PHP DateTime 物件 三大體系的互轉與查詢技巧。

MySQL 端:時間戳(INT)與日期函數互轉

核心轉換函數

函數用途範例
FROM_UNIXTIME(ts)時間戳 → DATETIMEFROM_UNIXTIME(1705300000) → '2024-01-15 10:13:20'
UNIX_TIMESTAMP(dt)DATETIME → 時間戳UNIX_TIMESTAMP('2024-01-15') → 1705248000
DATE(FROM_UNIXTIME(ts))時間戳 → DATE(僅日期)DATE(FROM_UNIXTIME(ts)) = '2024-01-15'

常用查詢模式(假設欄位 add_time 為 INT 時間戳)

-- 1. 最近 30 天(含今天)
WHERE DATE(FROM_UNIXTIME(add_time)) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)

-- 2. 本月資料
WHERE YEAR(FROM_UNIXTIME(add_time)) = YEAR(NOW())
  AND MONTH(FROM_UNIXTIME(add_time)) = MONTH(NOW())

-- 3. 今天資料
WHERE DATE(FROM_UNIXTIME(add_time)) = CURDATE()

-- 4. 指定日期範圍
WHERE FROM_UNIXTIME(add_time) BETWEEN '2024-01-01' AND '2024-01-31 23:59:59'

-- 5. 相對時間:N 天前
WHERE FROM_UNIXTIME(add_time) >= DATE_SUB(NOW(), INTERVAL 7 DAY)

提取年、月、日(用於 GROUP BY 統計)

SELECT 
    YEAR(FROM_UNIXTIME(add_time)) AS yr,
    MONTH(FROM_UNIXTIME(add_time)) AS mo,
    DAY(FROM_UNIXTIME(add_time)) AS dy,
    COUNT(*) AS cnt
FROM orders
GROUP BY yr, mo, dy
ORDER BY yr DESC, mo DESC, dy DESC;

MySQL 端:原生日期型別(DATE/DATETIME/TIMESTAMP)

若欄位已為日期型別,直接使用,無需 FROM_UNIXTIME:

-- 最近 30 天
WHERE date_col >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)

-- 本月
WHERE YEAR(date_col) = YEAR(CURDATE()) AND MONTH(date_col) = MONTH(CURDATE())

-- 今天
WHERE DATE(date_col) = CURDATE()

-- TO_DAYS 差值比較(舊寫法,效能較差)
WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30

PHP 端:DateTime 物件與時間戳互轉(PHP 5.3+ 推薦)

<?php
// 1. 現在時間
$now = new DateTime();                    // 預設伺服器時區
$now->setTimezone(new DateTimeZone('Asia/Taipei')); // 設定時區

// 2. 時間戳 → DateTime
$ts = 1705300000;
$dt = DateTime::createFromFormat('U', $ts); // 或 new DateTime("@$ts")
$dt->setTimezone(new DateTimeZone('Asia/Taipei'));

// 3. DateTime → 時間戳
$timestamp = $dt->getTimestamp();         // 等同 $dt->format('U')

// 4. 格式化輸出
echo $dt->format('Y-m-d H:i:s');          // 2024-01-15 10:13:20
echo $dt->format('Y年m月d日');            // 2024年01月15日

// 5. 日期運算
$dt->modify('+7 days');                   // 7 天后
$dt->modify('first day of this month');   // 本月第一天
$dt->modify('last day of -1 month');      // 上月最後一天

// 6. 比較兩個日期
$diff = $dt1->diff($dt2);
echo $diff->days;                         // 天數差
echo $diff->format('%R%a 天');            // +7 天 / -3 天

// 7. 判斷是否為今天
$today = new DateTime('today', new DateTimeZone('Asia/Taipei'));
if ($dt->format('Y-m-d') === $today->format('Y-m-d')) {
    echo '是今天';
}

時區陷阱與最佳實踐

  1. 資料庫儲存統一用 UTC:MySQL 設定 SET time_zone = '+00:00',PHP 預設時區設為 UTC(date_default_timezone_set('UTC')),僅在顯示層轉換使用者時區。
  2. 避免使用 date()、strtotime():舊函數易受時區、32 位元整數(2038 年問題)影響,一律改用 DateTime / DateTimeImmutable。
  3. 比較時務必同一時區:跨時區比較先 setTimezone() 統一,或都轉為 UTC 時間戳比較整數。

常見需求速查表

需求MySQL (時間戳)MySQL (日期型別)PHP DateTime
最近 N 天DATE(FROM_UNIXTIME(ts)) >= DATE_SUB(CURDATE(), INTERVAL N DAY)date_col >= DATE_SUB(CURDATE(), INTERVAL N DAY)$dt >= (new DateTime('-N days'))->setTimezone('UTC')
本月YEAR(FROM_UNIXTIME(ts))=YEAR(NOW()) AND MONTH(...)=MONTH(NOW())YEAR(date_col)=YEAR(CURDATE()) AND MONTH(date_col)=MONTH(CURDATE())$dt->format('Y-m') === (new DateTime())->format('Y-m')
今天DATE(FROM_UNIXTIME(ts)) = CURDATE()DATE(date_col) = CURDATE()$dt->format('Y-m-d') === (new DateTime('today'))->format('Y-m-d')
按月統計GROUP BY YEAR(FROM_UNIXTIME(ts)), MONTH(FROM_UNIXTIME(ts))GROUP BY YEAR(date_col), MONTH(date_col)// PHP 端分組較不適用,交給 SQL

總結

日期比較的核心原則:資料庫層盡量用原生日期型別、儲存統一 UTC、查詢利用索引友善寫法(避免函數包裹欄位);PHP 層一律用 DateTimeImmutable、明確設定時區、避免舊式函數。時間戳雖便於跨語言傳遞,但查詢時須轉換導致無法使用索引,大量資料建議改用 DATETIME + 索引。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved