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

PHP 日期時間加減運算完整指南:strtotime、DateTime、實用工具函式

     編輯:PHP 相關知識

前言

日期時間加減是業務邏輯常見需求:「5 個月後到期」、「上週一」、「距今 30 天」等。PHP 提供 `strtotime` 字串解析與 `DateTime` 物件導向兩套機制。本文系統整理兩者用法、常見陷阱、時區處理,並提供可直接部署的工具函式庫。

核心函式:strtotime 相對格式

$base = '2012-04-25 10:10:00';
$ts   = strtotime($base);           // 基準時間戳
$ts5m = strtotime('+5 months', $ts); // 加 5 個月
echo date('Y-m-d H:i:s', $ts5m);    // 2012-09-25 10:10:00

// 一行寫法
echo date('Y-m-d H:i:s', strtotime('+5 months', strtotime($base)));

常用相對格式速查表

格式說明範例
+1 day / -1 day加/減 1 天明天、昨天
+1 week / -2 weeks加/減 週一週後
+1 month / -3 months加/減月(自動處理月末)下個月同一天
+1 year / -10 years加/減年十年後
next Monday / last Friday下一個/上一個指定週日下週一
first day of next month下個月第一天月初計算
last day of February 2024該月最後一天月底計算
+1 week 2 days 4 hours 2 seconds混合單位複雜加減

DateTime 物件導向寫法(推薦 PHP 5.3+)

$dt = new DateTime('2012-04-25 10:10:00', new DateTimeZone('Asia/Taipei'));
$dt->modify('+5 months');
echo $dt->format('Y-m-d H:i:s'); // 2012-09-25 10:10:00

// 鏈式呼叫
echo (new DateTime('2012-04-25 10:10:00'))
    ->modify('+5 months')
    ->format('Y-m-d H:i:s');

// DateTimeImmutable (PHP 5.5+) 不修改原物件,回傳新實例
$dt = new DateTimeImmutable('2012-04-25 10:10:00');
$dt2 = $dt->modify('+5 months'); // $dt 不變,$dt2 為新日期

實用工具函式庫(支援字串/時間戳/DateTime 輸入)

<?php
function dt($input = 'now') {
    if ($input instanceof DateTimeInterface) return clone $input;
    if (is_numeric($input)) return (new DateTime('@'.$input))->setTimezone(new DateTimeZone(date_default_timezone_get()));
    return new DateTime($input);
}

function fmt($dt, $format = 'Y-m-d H:i:s') {
    return dt($dt)->format($format);
}

function add($dt, $interval) { return dt($dt)->modify($interval); }
function sub($dt, $interval) { return dt($dt)->modify('-'.$interval); }

function diffDays($dt1, $dt2) {
    $d1 = dt($dt1); $d2 = dt($dt2);
    return $d1->diff($d2)->days;
}

function getWeek($dt) {
    $w = dt($dt)->format('w');
    return $w == 0 ? 7 : $w; // 1=週一 ... 7=週日
}

function getTime($dt) { return fmt($dt, 'H:i'); }

function currentDateTime() { return fmt('now'); }

// 通用加減:支援 years, months, weeks, days, hours, minutes, seconds
function addInterval($dt, $value, $unit) { return add($dt, "+$value $unit"); }
function subInterval($dt, $value, $unit) { return sub($dt, "$value $unit"); }

使用範例

echo "今天: " . currentDateTime() . "\n";
echo "明天: " . fmt(addInterval('now', 1, 'day')) . "\n";
echo "上週一: " . fmt('last Monday') . "\n";
echo "下月初: " . fmt('first day of next month') . "\n";
echo "月底: " . fmt('last day of this month') . "\n";
echo "相差天數: " . diffDays('2024-01-01', '2024-02-01') . "\n";

關鍵陷阱與最佳實踐

  1. 時區必須統一設定:`date_default_timezone_set('Asia/Taipei')` 放在入口檔最頂端。`strtotime` 依賴預設時區,`DateTime` 建構時建議明確傳入 `DateTimeZone`。
  2. 月份加減的月末邊界:`strtotime('+1 month', strtotime('2024-01-31'))` → `2024-03-02`(因 2 月無 31 日)。`DateTime::modify` 行為相同。若需「同月同日或該月最後一天」,需自行邏輯處理。
  3. 夏令時間(DST):跨 DST 邊界加減小時可能導致 23/25 小時一天。使用 `DateTime` + 具體時區可正確處理。
  4. 避免 `date('w')` 直接運算**:`date('w')` 回傳 0(日)~6(六),邏輯易錯。用 `DateTime::format('N')` 取 1(一)~7(日) 較直觀。
  5. 資料庫存儲用 UTC:PHP 處理時轉換為使用者時區,存回 DB 前轉 UTC(`$dt->setTimezone(new DateTimeZone('UTC'))`)。

總結

`strtotime` 適合簡單、一次性字串解析;`DateTime`/`DateTimeImmutable` 適合複雜運算、時區處理、不可變傳遞、鏈式呼叫。建立統一的 `dt()`/`fmt()`/`addInterval()` 等工具函式,全專案統一呼叫,消除時區 Bug、格式不一、邏輯重複。

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