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
相关产品推荐
相关产品推荐

