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

PHP 產生相對時間字串:幾秒前、幾分鐘前、幾天前、幾週前

     編輯:PHP 相關知識

PHP 相對時間格式化:人性化顯示「X 分鐘前」、「Y 天前」完整函式

社群、論壇、動態牆常需顯示「3 分鐘前」、「2 天前」而非絕對時間。本文提供支援多語系、可擴充閾值的相對時間函式。

核心函式

<?php
function time_ago(DateTimeInterface|string|int $time, string $locale = 'zh_TW'): string {
    $now = new DateTime();
    $then = $time instanceof DateTimeInterface
        ? clone $time
        : (is_int($time) ? (new DateTime())->setTimestamp($time) : new DateTime($time));

    $diff = $now->getTimestamp() - $then->getTimestamp();
    if ($diff < 0) $diff = 0; // 未來時間視為剛剛

    $intervals = [
        'year'   => 31556926, // 365.25 天
        'month'  => 2629743,  // 30.44 天
        'week'   => 604800,
        'day'    => 86400,
        'hour'   => 3600,
        'minute' => 60,
        'second' => 1,
    ];

    $labels = [
        'zh_TW' => [
            'year' => ['年', '年前'], 'month' => ['個月', '個月前'],
            'week' => ['週', '週前'], 'day' => ['天', '天前'],
            'hour' => ['小時', '小時前'], 'minute' => ['分鐘', '分鐘前'],
            'second' => ['秒', '秒前'], 'just_now' => '剛剛',
        ],
        'en' => [
            'year' => ['year', 'years ago'], 'month' => ['month', 'months ago'],
            'week' => ['week', 'weeks ago'], 'day' => ['day', 'days ago'],
            'hour' => ['hour', 'hours ago'], 'minute' => ['minute', 'minutes ago'],
            'second' => ['second', 'seconds ago'], 'just_now' => 'just now',
        ],
    ];

    $lang = $labels[$locale] ?? $labels['en'];

    foreach ($intervals as $unit => $seconds) {
        $count = floor($diff / $seconds);
        if ($count >= 1) {
            $label = $count === 1 ? $lang[$unit][0] : $lang[$unit][1];
            return $count . $label;
        }
    }
    return $lang['just_now'];
}

// 使用範例
echo time_ago('-5 minutes');      // 5分鐘前
echo time_ago('-2 hours');        // 2小時前
echo time_ago('-3 days');         // 3天前
echo time_ago('-1 week');         // 1週前
echo time_ago('2024-01-01');      // 幾個月前
echo time_ago(time() - 30);       // 30秒前
echo time_ago(time());            // 剛剛
?>

進階:支援未來時間「X 分鐘後」

function time_diff(DateTimeInterface|string|int $from, DateTimeInterface|string|int $to = null, string $locale = 'zh_TW'): string {
    $from = $from instanceof DateTimeInterface ? clone $from : (is_int($from) ? (new DateTime())->setTimestamp($from) : new DateTime($from));
    $to = $to ?? new DateTime();
    $to = $to instanceof DateTimeInterface ? clone $to : (is_int($to) ? (new DateTime())->setTimestamp($to) : new DateTime($to));

    $diff = $to->getTimestamp() - $from->getTimestamp();
    $past = $diff >= 0;
    $diff = abs($diff);
    // ... 同 time_ago 邏輯 ...
    $suffix = $past ? '前' : '後';
    return $count . $lang[$unit][0] . $suffix;
}

效能優化:快取 DateTime 物件

// 在迴圈中重用 DateTime
$now = new DateTime();
foreach ($posts as $post) {
    $postTime = DateTime::createFromFormat('U', $post['created_at']);
    $diff = $now->getTimestamp() - $postTime->getTimestamp();
    // ...
}

前端替代方案:timeago.js

<time class="timeago" datetime="2024-01-15T14:30:00+08:00">2024-01-15 14:30</time>
<script src="https://cdn.jsdelivr.net/npm/timeago.js@4"></script>
<script> timeago().render(document.querySelectorAll('.timeago')); </script>

優點:瀏覽器自動更新、支援 40+ 語系、無伺服器負擔。缺點:需前端渲染、SEO 需輸出 datetime 屬性。

資料庫層面優化

-- MySQL 直接算相對秒數
SELECT UNIX_TIMESTAMP() - UNIX_TIMESTAMP(created_at) AS diff_seconds FROM posts;

減少 PHP 端物件建立開銷,大量列表顯示時效能顯著提升。

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