You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:18:20