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

PHP计算用户注册周年数结果少1年,求问题原因及解决办法

注册周年蛋糕图标计算少1年的问题排查

我写了一个函数,用来在用户注册周年当天显示蛋糕图标,但计算出的周年数总是少1年。

原函数代码:

public function cake_day($reg_date, $username)
{
    $date1 = new DateTime();
    $date1->setTimestamp($reg_date);
    
    $date2 = new DateTime();
    
    $cake_icon = '';
    if ($date1->format('d-m') === $date2->format('d-m')) 
    {
        // calculate how many years
        $total_years = $date1->diff($date2)->format('%y');
        if ($total_years > 0)
        {
            $cake_icon = '<img src="/templates/default/images/cake.png" alt="'.$total_years.' years" class="tooltip-top" title="'.$username.' has been here for '.$total_years.' years" />';
        }
    }
    return $cake_icon;
}

示例测试日期:

Registered - 19 February 2022 at 8:55 pm UTC (as a timestamp 1645304121)
Today - 19 February 2024 at 11:22 am UTC

按这个日期计算,应该显示2年,但实际只返回1年,请问哪里出错了?


问题原因与修复方案

问题原因

DateTime::diff()的%y格式符返回的是两个日期之间的完整周年数,只有当当前时间完全超过注册时间的时分秒时,才会被算作完整的一年。

在你的测试案例中:

  • 注册时间是2022-02-19 20:55:00
  • 当前时间是2024-02-19 11:22:00

当前时间的时分秒早于注册时间,所以diff()判定还未达到完整的2周年,仅返回1年。

修复方案一(推荐)

既然已经通过d-m判断当天是注册纪念日,完全可以忽略时分秒的影响,直接用当前年份减去注册年份:

public function cake_day($reg_date, $username)
{
    $date1 = new DateTime();
    $date1->setTimestamp($reg_date);
    
    $date2 = new DateTime();
    
    $cake_icon = '';
    if ($date1->format('d-m') === $date2->format('d-m')) 
    {
        // 直接计算年份差,忽略时分秒
        $total_years = (int)$date2->format('Y') - (int)$date1->format('Y');
        if ($total_years > 0)
        {
            $cake_icon = '<img src="/templates/default/images/cake.png" alt="'.$total_years.' years" class="tooltip-top" title="'.$username.' has been here for '.$total_years.' years" />';
        }
    }
    return $cake_icon;
}

修复方案二(保留diff用法)

如果一定要使用diff(),可以先将两个日期的时分秒清零,再计算差值:

public function cake_day($reg_date, $username)
{
    $date1 = new DateTime();
    $date1->setTimestamp($reg_date);
    // 清零时分秒,统一到当天凌晨
    $date1->setTime(0, 0, 0);
    
    $date2 = new DateTime();
    $date2->setTime(0, 0, 0);
    
    $cake_icon = '';
    if ($date1->format('d-m') === $date2->format('d-m')) 
    {
        $total_years = $date1->diff($date2)->format('%y');
        if ($total_years > 0)
        {
            $cake_icon = '<img src="/templates/default/images/cake.png" alt="'.$total_years.' years" class="tooltip-top" title="'.$username.' has been here for '.$total_years.' years" />';
        }
    }
    return $cake_icon;
}

内容的提问来源于stack exchange,提问作者NaughtySquid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:43:39