在社交動態、評論列表等場景中,常需將絕對時間(如 2024-01-15 14:30:00)轉換為人類易讀的相對時間(如「3天前」、「5分鐘前」)。本文提供一個實用的 PHP 函數實現此功能。
<?php
/**
* 將日期時間轉換為相對時間字符串
* 例如:2 days ago, 3 minutes ago, 1 year ago
*
* @param string $d MySQL datetime 格式字符串
* @return string 相對時間描述
*/
function ago($d) {
$c = getdate(); // 當前時間數組
$p = array('year', 'mon', 'mday', 'hours', 'minutes', 'seconds');
$display = array('year', 'month', 'day', 'hour', 'minute', 'second');
$factor = array(0, 12, 30, 24, 60, 60); // 進制基數
$d = datetoarr($d); // 解析輸入時間
for ($w = 0; $w < 6; $w++) {
if ($w > 0) {
// 累加進位:月→日、日→時等
$c[$p[$w]] += $c[$p[$w-1]] * $factor[$w];
$d[$p[$w]] += $d[$p[$w-1]] * $factor[$w];
}
// 計算差值
if ($c[$p[$w]] - $d[$p[$w]] > 1) {
return ($c[$p[$w]] - $d[$p[$w]]) . ' ' . $display[$w] . 's ago';
}
}
return 'just now';
}
/**
* 解析 MySQL datetime 字符串為關聯數組
* 格式:YYYY-MM-DD HH:MM:SS
*/
function datetoarr($d) {
preg_match(
"/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/",
$d,
$matches
);
return array(
'seconds' => $matches[6],
'minutes' => $matches[5],
'hours' => $matches[4],
'mday' => $matches[3],
'mon' => $matches[2],
'year' => $matches[1],
);
}
// 使用示例
echo ago('2024-01-10 12:00:00'); // 輸出類似 "5 days ago"
?>
上述代碼邏輯較舊,現代 PHP 專案建議使用 DateTime 類與 DateInterval 實現更健壯的版本:
function timeAgo(string $datetime): string {
$now = new DateTime();
$then = new DateTime($datetime);
$diff = $now->diff($then);
$units = [
'y' => '年',
'm' => '月',
'd' => '天',
'h' => '小時',
'i' => '分鐘',
's' => '秒',
];
foreach ($units as $key => $label) {
if ($diff->$key > 0) {
return $diff->$key . $label . '前';
}
}
return '剛剛';
}
相對時間格式能顯著提升用戶體驗,讓時間信息更直觀易懂。