$start = mktime(0,0,0, 5,3,1998); // 1998-05-03 $end = mktime(0,0,0, 6,5,1999); // 1999-06-05 $days = round(($end - $start) / 86400); // 86400 = 24*3600 echo $days; // 398
優點:純整數運算,極快;缺點:受 32 位系統 2038 年問題限制(PHP 7.1+ 64 位無憂)。
$start = new DateTime('1998-05-03');
$end = new DateTime('1999-06-05');
$diff = $start->diff($end);
echo $diff->days; // 總天數
echo $diff->format('%y年%m月%d天'); // 1年1月2天
echo $diff->h.'小時'.$diff->i.'分'; // 時分秒
$days = (strtotime('1999-06-05') - strtotime('1998-05-03')) / 86400;
SELECT DATEDIFF('1999-06-05', '1998-05-03'); -- 398
SELECT TIMESTAMPDIFF(DAY, '1998-05-03', '1999-06-05'); -- 398 SELECT TIMESTAMPDIFF(MONTH, '1998-05-03', '1999-06-05'); -- 13 SELECT TIMESTAMPDIFF(SECOND, '1998-05-03 10:00', '1998-05-03 10:01'); -- 60
SELECT (UNIX_TIMESTAMP('1999-06-05') - UNIX_TIMESTAMP('1998-05-03')) / 86400;
CREATE TABLE loans (
id INT PRIMARY KEY,
borrow_date DATE,
return_date DATE,
days_diff INT
);
CREATE TRIGGER update_days_diff
BEFORE INSERT ON loans
FOR EACH ROW
SET NEW.days_diff = DATEDIFF(NEW.return_date, NEW.borrow_date);
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| PHP 邏輯中臨時計算 | DateTime::diff() | 面向對象、可讀性強、無年份限制 |
| 高頻計算、性能敏感 | 時間戳減法 | 純整數運算最快 |
| SQL 查詢過濾/排序 | TIMESTAMPDIFF() | 下推到存儲層,利用索引 |
| 需持久化差值字段 | 觸發器 + DATEDIFF | 寫入時自動計算,讀取零成本 |
| 跨時區業務 | DateTime + DateTimeZone | PHP 原生支援時區轉換 |
DateTime::diff 自動處理,時間戳法需注意 86400 非恆定(夏令時切換日)。DATEDIFF('2024-01-02', '2024-01-01') = 1,不含起始日。IFNULL 處理。