PHP time_ago函数在RTL布局下时间格式错误如何修复
问题描述
现有time_ago函数可实现相对时间计算输出,默认返回now、2 seconds ago这类格式的相对时间结果。
但在RTL(从右到左)语言布局场景下,该函数返回的时间格式显示错误,需要将表示“之前”的ago标识从时间文本末尾调整到文本开头位置,适配RTL显示规则。
当前原有函数实现代码如下:
if ( ! function_exists('time_ago')) { function time_ago($datetime, $text = '') { $full = false; $now = new DateTime; $ago = new DateTime($datetime); $diff = $now->diff($ago); $diff->w = floor($diff->d / 7); $diff->d -= $diff->w * 7; $string = array( 'y' => lang('common_year'), 'm' => lang('common_month'), 'w' => lang('common_week'), 'd' => lang('common_day'), 'h' => lang('common_hour'), 'i' => lang('common_minute'), 's' => lang('common_second'), ); foreach ($string as $k => &$v) { if ($diff->$k) { $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? '' : ''); } else { unset($string[$k]); } } if (!$full) $string = array_slice($string, 0, 1); return strtolower($text).' '.($string ? implode(', ', $string) . ' '.lang('common_ago') : ' '.lang('common_now')); } }
修改方案
不要硬编码把ago移到开头,否则会破坏LTR(从左到右)语言的正常显示,推荐增加RTL状态判断,根据当前语言布局自动调整拼接顺序:
- 如果你项目中有全局判断当前是否为RTL语言的公共方法(比如
is_rtl()),直接调用即可 - 如果没有现成判断方法,也可以给函数新增
$is_rtl参数,手动传入当前布局状态 - 仅在存在具体时间差值(即不是
now的场景)调整ago的位置,now场景无需改动
修改后的完整代码如下:
if ( ! function_exists('time_ago')) { function time_ago($datetime, $text = '', $is_rtl = false) { $full = false; // 如果项目有全局RTL判断方法,替换下面这行的赋值即可 // $is_rtl = is_rtl(); $now = new DateTime; $ago = new DateTime($datetime); $diff = $now->diff($ago); $diff->w = floor($diff->d / 7); $diff->d -= $diff->w * 7; $string = array( 'y' => lang('common_year'), 'm' => lang('common_month'), 'w' => lang('common_week'), 'd' => lang('common_day'), 'h' => lang('common_hour'), 'i' => lang('common_minute'), 's' => lang('common_second'), ); foreach ($string as $k => &$v) { if ($diff->$k) { $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? '' : ''); } else { unset($string[$k]); } } if (!$full) $string = array_slice($string, 0, 1); $prefix = strtolower($text) . ' '; if ($string) { $time_str = implode(', ', $string); $ago_text = lang('common_ago'); // RTL场景下ago放在时间前面,LTR场景放在后面 $result = $is_rtl ? $prefix . $ago_text . ' ' . $time_str : $prefix . $time_str . ' ' . $ago_text; } else { $result = $prefix . lang('common_now'); } return $result; } }
调用说明
- LTR语言场景下正常调用即可:
echo time_ago('2024-01-01 12:00:00');输出格式和原来一致,比如2 seconds ago - RTL语言场景下传入RTL标识:
echo time_ago('2024-01-01 12:00:00', '', true);会自动把ago放在时间文本开头,适配RTL布局显示。
内容的提问来源于stack exchange,提问作者abdo kamel
相关产品推荐
相关产品推荐

