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

PHP 日期時間處理大全:時間戳、格式化、計算、DateAdd/DateDiff 移植實現

     編輯:PHP 相關知識

PHP 日期時間處理核心在於 Unix 時間戳(自 1970-01-01 秒數)。本文系統梳理獲取、格式化、轉換、加減運算、差值計算,並移植 ASP 經典 DateAdd/DateDiff 函數為 PHP 版本。

核心概念:Unix 時間戳

time();           // 當前時間戳 (int)
microtime(true);  // 含微秒 (float)
strtotime('+1 day'); // 相對時間解析
  • 跨平台一致(Windows/Linux 同標準);
  • 整數便於資料庫存儲、比較、傳輸;
  • 32 位系統 2038 年溢出,64 位無憂。

格式化輸出:date() vs strftime()

常用格式字符速查

Y-m-d H:i:s     // 2024-01-15 14:30:59
Y/m/d           // 2024/01/15
l, F j, Y       // Monday, January 15, 2024
D, M j          // Mon, Jan 15
H:i             // 14:30 (24h)
h:i A           // 02:30 PM
U               // 時間戳
c               // ISO 8601: 2024-01-15T14:30:59+08:00
r               // RFC 2822: Mon, 15 Jan 2024 14:30:59 +0800

字串轉時間戳:strtotime() 與 DateTime

strtotime('2024-01-15');           // 精確日期
strtotime('+1 week');              // 相對時間
strtotime('next Monday');          // 自然語言
strtotime('2024-01-15 14:30:59');  // 完整時間

// 更強大的 DateTime
$dt = new DateTime('2024-01-15 14:30:59', new DateTimeZone('Asia/Shanghai'));
$ts = $dt->getTimestamp();

日期加減運算

方法一:strtotime 相對格式(簡單)

strtotime('+1 day', $ts);
strtotime('-3 months', $ts);
strtotime('+1 year +2 months -5 days', $ts);

方法二:DateTime modify(推薦,鏈式)

$dt = new DateTime('@' . $ts);
$dt->modify('+1 day')->modify('-3 hours');
echo $dt->format('Y-m-d H:i:s');

方法三:DateInterval(精確控制)

$dt->add(new DateInterval('P1Y2M3D'));   // 加 1年2月3日
$dt->sub(new DateInterval('PT5H30M'));   // 減 5小時30分

兩日期差值計算

方法一:時間戳相減(秒數)

$diff_sec = $ts2 - $ts1;
$days = intdiv($diff_sec, 86400);

方法二:DateTime::diff(精確、可讀)

$dt1 = new DateTime('@' . $ts1);
$dt2 = new DateTime('@' . $ts2);
$interval = $dt1->diff($dt2);

echo $interval->days;        // 總天數
echo $interval->h;           // 小時部分
echo $interval->format('%a 天 %h 小時 %i 分'); // 格式化

移植 ASP DateAdd / DateDiff

/**
 * ASP DateAdd 兼容實現
 * @param string $interval  yyyy|q|m|y|d|w|ww|h|n|s
 * @param int $number
 * @param int $timestamp
 * @return int 新時間戳
 */
function DateAdd(string $interval, int $number, int $timestamp): int {
    $dt = new DateTime('@' . $timestamp);
    $dt->setTimezone(new DateTimeZone('UTC')); // 避免 DST 干擾

    $map = [
        'yyyy' => 'years', 'q' => 'quarters', 'm' => 'months',
        'y' => 'days', 'd' => 'days', 'w' => 'days', 'ww' => 'weeks',
        'h' => 'hours', 'n' => 'minutes', 's' => 'seconds'
    ];
    $unit = $map[$interval] ?? 'days';
    $num = $number * ($interval === 'q' ? 3 : ($interval === 'ww' ? 7 : 1));

    $dt->add(new DateInterval("P{$num}{$unit[0]}")); // 簡化,實際需構建完整 ISO 間隔
    // 完整實現建議用 switch 分支構建 DateInterval
    return $dt->getTimestamp();
}

/**
 * ASP DateDiff 兼容實現
 * @param string $interval  w|d|h|n|s
 * @param int $ts1
 * @param int $ts2
 * @return int 差值($ts2 - $ts1)
 */
function DateDiff(string $interval, int $ts1, int $ts2): int {
    $diff = $ts2 - $ts1;
    return match ($interval) {
        'w' => intdiv($diff, 604800),
        'd' => intdiv($diff, 86400),
        'h' => intdiv($diff, 3600),
        'n' => intdiv($diff, 60),
        's' => $diff,
        default => 0
    };
}

實用工具函數庫

// 獲取本週一 00:00:00 時間戳
function week_start(int $ts = null): int {
    $dt = $ts ? new DateTime('@' . $ts) : new DateTime();
    $dt->modify('this week Monday 00:00:00');
    return $dt->getTimestamp();
}

// 獲取本月第一天 00:00:00
function month_start(int $ts = null): int {
    $dt = $ts ? new DateTime('@' . $ts) : new DateTime();
    $dt->modify('first day of this month 00:00:00');
    return $dt->getTimestamp();
}

// 友好時間顯示(剛剛、X分鐘前、X小時前、昨天、日期)
function human_time(int $ts): string {
    $diff = time() - $ts;
    if ($diff < 60) return '剛剛';
    if ($diff < 3600) return intdiv($diff, 60) . '分鐘前';
    if ($diff < 86400) return intdiv($diff, 3600) . '小時前';
    if ($diff < 172800) return '昨天 ' . date('H:i', $ts);
    return date('m-d H:i', $ts);
}

最佳實踐清單

  1. 統一儲存 UTC 時間戳,業務層按用戶時區格式化;
  2. 使用 DateTime 類,避免 32 位溢出、自動處理 DST;
  3. 資料庫用 TIMESTAMP/DATETIME,配合 ORM 自動轉換;
  4. 定時任務用 cron 表達式,不要用睡眠循環;
  5. 測試邊界:閏年、夏令時切換、跨月、跨年。

掌握時間戳 + DateTime 雙工具箱,能優雅解決所有日期時間業務。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數優點缺點適用場景
date()格式字符豐富、無 locale 依賴需轉義字面字符通用格式化、API 輸出
strftime()支援 locale 本地化、% 格式直觀依賴系統 locale、Windows 支援弱多語言項目、報表導出
DateTime::format()OO 風格、鏈式調用、時區感知稍繁瑣現代代碼、複雜時區邏輯