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

PHP 秒數格式化為人類可讀時間:自定義函數與最佳實踐

     編輯:PHP 綜合知識

核心函數實現

/**

 * 將秒數格式化為中文可讀時間
 * @param int $seconds 秒數
 * @return string 格式化字符串,如 "1天2小時30分5秒"
 */
function formatDuration(int $seconds): string {
    if ($seconds < 0) $seconds = 0;
    
    $units = [
        86400 => '天',
        3600  => '小時',
        60    => '分',
        1     => '秒'
    ];
    
    $parts = [];
    foreach ($units as $unitSeconds => $unitName) {
        if ($seconds >= $unitSeconds) {
            $value = (int)($seconds / $unitSeconds);
            $parts[] = $value . $unitName;
            $seconds %= $unitSeconds;
        }
    }
    
    return $parts ? implode('', $parts) : '0秒';
}

// 測試
echo formatDuration(86465);  // 1天1分5秒
echo formatDuration(3661);   // 1小時1分1秒
echo formatDuration(45);     // 45秒
echo formatDuration(0);      // 0秒

進階版:支援多語言、精度控制、零值顯示

/**

 * 進階時間格式化
 * @param int $seconds
 * @param array $options [
 *     'lang' => 'zh|en',           // 語言
 *     'precision' => 2,            // 最大顯示單位數
 *     'showZero' => false,         // 是否顯示 0 值單位
 *     'separator' => '',           // 單位分隔符
 *     'short' => false             // 短格式:1d 2h 3m 4s
 * ]
 */
function formatDurationAdvanced(int $seconds, array $options = []): string {
    $opts = array_merge([
        'lang' => 'zh',
        'precision' => 4,
        'showZero' => false,
        'separator' => '',
        'short' => false
    ], $options);
    
    if ($seconds < 0) $seconds = 0;
    
    $units = $opts['lang'] === 'en' ? [
        86400 => $opts['short'] ? 'd' : ' day',
        3600  => $opts['short'] ? 'h' : ' hour',
        60    => $opts['short'] ? 'm' : ' minute',
        1     => $opts['short'] ? 's' : ' second'
    ] : [
        86400 => $opts['short'] ? '天' : '天',
        3600  => $opts['short'] ? '時' : '小時',
        60    => $opts['short'] ? '分' : '分',
        1     => $opts['short'] ? '秒' : '秒'
    ];
    
    $parts = [];
    foreach ($units as $unitSeconds => $unitName) {
        if (count($parts) >= $opts['precision']) break;
        
        $value = (int)($seconds / $unitSeconds);
        if ($value > 0 || $opts['showZero']) {
            $suffix = $opts['short'] ? '' : ($opts['lang'] === 'en' && $value > 1 ? 's' : '');
            $parts[] = $value . $opts['separator'] . $unitName . $suffix;
            $seconds %= $unitSeconds;
        }
    }
    
    return $parts ? implode($opts['separator'] ? ' ' : '', $parts) : ($opts['short'] ? '0s' : '0秒');
}

// 使用範例
echo formatDurationAdvanced(90061);                          // 1天1小時1分1秒
echo formatDurationAdvanced(90061, ['precision' => 2]);      // 1天1小時
echo formatDurationAdvanced(90061, ['lang' => 'en']);        // 1 day 1 hour 1 minute 1 second
echo formatDurationAdvanced(90061, ['short' => true]);       // 1天1時1分1秒
echo formatDurationAdvanced(90061, ['separator' => ' ']);    // 1 天 1 小時 1 分 1 秒

Carbon 庫方案(現代 PHP 專案推薦)

// composer require nesbot/carbon
use Carbon\CarbonInterval;

$interval = CarbonInterval::seconds(90061);

// 人類可讀
echo $interval->forHumans();           // "1 day 1 hour 1 minute 1 second"
echo $interval->forHumans(['short' => true]); // "1d 1h 1m 1s"
echo $interval->forHumans(['parts' => 2]);    // "1 day 1 hour"
echo $interval->forHumans(['locale' => 'zh']); // "1天 1小時 1分鐘 1秒" (需 Carbon 2.50+)

// 精確格式化
echo $interval->cascade()->format('%d天 %h小時 %i分 %s秒'); // 1天 1小時 1分 1秒

DateInterval 原生方案(無依賴)

function formatDurationNative(int $seconds): string {
    $interval = new DateInterval('PT' . $seconds . 'S');
    // DateInterval 不自動進位,需手動計算
    $days = (int)($seconds / 86400);
    $hours = (int)(($seconds % 86400) / 3600);
    $minutes = (int)(($seconds % 3600) / 60);
    $secs = $seconds % 60;
    
    $parts = [];
    if ($days) $parts[] = $days . '天';
    if ($hours) $parts[] = $hours . '小時';
    if ($minutes) $parts[] = $minutes . '分';
    if ($secs || empty($parts)) $parts[] = $secs . '秒';
    
    return implode('', $parts);
}

性能對比

方案執行時間 (100萬次)依賴功能豐富度
自定義函數~0.15s無基礎
DateInterval~0.45s無中等
CarbonInterval~1.2sComposer極豐富

常見應用場景

場景推薦方案範例
視頻/音頻時長顯示自定義函數 / Carbon1:23:45
相對時間(幾分鐘前)Carbon diffForHumans()5分鐘前
倒計時器自定義函數 + JS 前端剩餘 2天3小時
日誌/審計持續時間Carbon forHumans()執行耗時 1.5秒
高性能批量處理自定義函數百萬級數據轉換

總結

  • 簡單項目/高性能需求:自定義函數(~10 行代碼,零依賴)
  • 現代 Laravel/Symfony 專案:Carbon(功能完整、國際化、鏈式調用)
  • 需精確控制格式:DateInterval + 手動計算 或 Carbon cascade()->format()
  • 核心算法:除法取商取模,從大單位到小單位依次處理

秒數格式化看似簡單,但處理邊界條件(0值、負數)、國際化、精度控制時易出錯。封裝通用函數或引入成熟庫,能避免重複造輪子並保證一致性。

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