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

PHP 精確計算兩日期差距:年、月、日、時、分、秒完整演算法

     編輯:PHP 相關知識

PHP 精確計算兩日期差距:年、月、日、時、分、秒完整演算法

網路上常見的「相減秒數再除 365/30/24」法,無法正確處理閏年、大小月、閏秒等情況。本文提供一個考慮實際行事曆的 diffDateTime 方法,精確輸出年、月、日、時、分、秒差距。

核心代碼

class Utils {
    /** 將 MySQL DATETIME 轉為 Unix 時間戳 */
    public function fmDatetime($datetime) {
        $y = substr($datetime, 0, 4);
        $m = substr($datetime, 5, 2);
        $d = substr($datetime, 8, 2);
        $h = substr($datetime, 11, 2);
        $i = substr($datetime, 14, 2);
        $s = substr($datetime, 17, 2);
        return mktime($h, $i, $s, $m, $d, $y);
    }

    /** 計算詳細差距 */
    private function diffDateTime($start, $end) {
        $rs = [];
        $sY = (int)substr($start, 0, 4);
        $eY = (int)substr($end, 0, 4);
        $sM = (int)substr($start, 5, 2);
        $eM = (int)substr($end, 5, 2);
        $sD = (int)substr($start, 8, 2);
        $eD = (int)substr($end, 8, 2);

        $startTime = $this->fmDatetime($start);
        $endTime   = $this->fmDatetime($end);
        $diffSec   = $endTime - $startTime;

        // 秒、分、時、日、週(以秒換算)
        $rs['second'] = $diffSec;
        $rs['minute'] = ceil($diffSec / 60);
        $rs['hour']   = ceil($diffSec / 3600);
        $rs['day']    = ceil($diffSec / 86400);
        $rs['week']   = ceil($rs['day'] / 7);

        // 月、年(依實際月份差計算)
        $monthDiff = ($eY - $sY) * 12 + ($eM - $sM);
        $yearDiff  = $eY - $sY;

        // 微調:若結束日 < 開始日,月份 -1
        if ($eD < $sD) $monthDiff--;

        // 若月份差為負,年份 -1
        if ($monthDiff < 0) {
            $yearDiff--;
            $monthDiff += 12;
        }

        $rs['month'] = $monthDiff;
        $rs['year']  = $yearDiff;

        return $rs;
    }
}

使用範例

$utils = new Utils();
$diff = $utils->diffDateTime('2023-01-31 00:00:00', '2023-03-01 00:00:00');
print_r($diff);
/*
Array(
    [second] => 2505600
    [minute] => 41760
    [hour]   => 696
    [day]    => 29
    [week]   => 5
    [month]  => 1   // 1月31到3月1 算 1 個月
    [year]   => 0
)
*/

關鍵邏輯說明

  1. 先以秒數換算日、時、分、秒、週(向上取整)。
  2. 月份差 = (年差×12) + 月差,再根據「日」是否跨月微調。
  3. 年份差 = 年份相減,若月份差為負則年份 -1。
  4. 此演算法符合人類直覺的「年/月」計算方式,而非單純天數除法。

適用場景

  • 會員資歷顯示(如「註冊 3 年 2 月 10 天」)。
  • 訂單/合約剩餘時間精確倒數。
  • 任何需精確到「月」的商業邏輯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved