微博、QQ 空間等社交應用常見的「剛剛」、「5 分鐘前」、「昨天 14:30」等友好時間格式,能顯著提升用戶體驗。本文提供一個功能完整、邏輯清晰的 PHP 實現函數。
| 時間跨度 | 顯示格式 | 示例 |
|---|---|---|
| 跨年且 > 3 天 | 完整日期 | 2023-12-25 |
| 今天 < 1 分鐘 | 秒前 | 30 秒前 |
| 今天 1-60 分鐘 | 分鐘前 | 15 分鐘前 |
| 今天 > 1 小時 | 小時前 | 3 小時前 |
| 昨天 | 昨天 HH:MM | 昨天 14:30 |
| 前天 | 前天 HH:MM | 前天 09:15 |
| 3-365 天(未跨年) | 月日 | 05 月 20 號 |
<?php
/**
* 格式化友好時間顯示
* @param int $time Unix 時間戳
* @return string
*/
function formatTime($time) {
$now = time();
$day = date('Y-m-d', $time);
$today = date('Y-m-d');
$dayArr = explode('-', $day);
$todayArr = explode('-', $today);
// 粗略天數差(30 天內準確,跨月可能有 1 天誤差)
$days = ($todayArr[0] - $dayArr[0]) * 365
+ ($todayArr[1] - $dayArr[1]) * 30
+ ($todayArr[2] - $dayArr[2]);
$secs = $now - $time; // 秒數差
// 跨年且超過 3 天
if ($todayArr[0] - $dayArr[0] > 0 && $days > 3) {
return date('Y-m-d', $time);
}
// 同一年內
if ($days < 1) { // 今天
if ($secs < 60) return $secs . '秒前';
elseif ($secs < 3600) return floor($secs / 60) . '分鐘前';
else return floor($secs / 3600) . '小時前';
} elseif ($days < 2) { // 昨天
return '昨天' . date('H:i', $time);
} elseif ($days < 3) { // 前天
return '前天' . date('H:i', $time);
} else { // 3 天前(未跨年)
return date('m月d日', $time);
}
}
// 測試
echo formatTime(time() - 30) . "\n"; // 30秒前
echo formatTime(time() - 3600) . "\n"; // 1小時前
echo formatTime(time() - 86400) . "\n"; // 昨天...
echo formatTime(time() - 86400 * 10) . "\n"; // 10天前...
?>
<?php
function formatTimePrecise($time) {
$now = time();
$todayStart = strtotime(date('Y-m-d'));
$targetStart = strtotime(date('Y-m-d', $time));
$days = ($todayStart - $targetStart) / 86400; // 精確天數
$secs = $now - $time;
if ($days >= 365 || ($days > 3 && date('Y', $time) != date('Y'))) {
return date('Y-m-d', $time);
}
if ($days < 1) {
if ($secs < 60) return $secs . '秒前';
if ($secs < 3600) return floor($secs / 60) . '分鐘前';
return floor($secs / 3600) . '小時前';
}
if ($days < 2) return '昨天 ' . date('H:i', $time);
if ($days < 3) return '前天 ' . date('H:i', $time);
return date('m月d日', $time);
}
?>
後端返回標準 ISO 8601 時間(2024-01-15T14:30:00+08:00),前端使用 Day.js 或 Moment.js 實現:
// Day.js 示例
dayjs.extend(relativeTime);
dayjs('2024-01-15T14:30:00+08:00').fromNow(); // "2 小時前"
優勢:自動適應用戶語言、時區、實時更新無需輪詢。
date_default_timezone_set('Asia/Shanghai'))$secs < 0 判斷,返回「剛剛」或拋出異常靈活選擇後端或前端實現,讓時間顯示更貼近用戶直覺。