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

PHP中gmstrftime过时,替换datefmt_format报错求助

解决PHP中gmstrftime过时替换为IntlDateFormatter的错误问题

问题背景

原代码中使用的gmstrftime函数已过时,尝试替换为datefmt_format时触发以下错误:

Fatal error: Uncaught TypeError: datefmt_format(): Argument #1 ($formatter) must be of type IntlDateFormatter, string given

错误原因

datefmt_format的第一个参数必须是IntlDateFormatter类的实例,而非直接传入格式化字符串。你之前的用法完全误解了该函数的调用逻辑。

修正方案

原代码用于生成葡萄牙语日历(从mes_pt数组的葡语月份名称可判断),且gmstrftime基于GMT时区工作,因此我们需要先创建对应配置的IntlDateFormatter实例,再用它来格式化时间戳。

完整修正后的代码片段

function generate_calendar($year, $month, $days = array(), $day_name_length = 3, $month_href = NULL, $first_day = 0, $pn = array()){
  $first_of_month = gmmktime(0,0,0,$month,1,$year);
  
  // 创建葡萄牙语、GMT时区的日期格式化器(巴西葡语可将pt_PT改为pt_BR)
  $formatter = new IntlDateFormatter(
      'pt_PT',
      IntlDateFormatter::FULL,
      IntlDateFormatter::NONE,
      'GMT',
      IntlDateFormatter::GREGORIAN
  );

  $day_names = array();
  for($n=0,$t=(3+$first_day)*86400; $n<7; $n++,$t+=86400) {
      // 设置模式为完整星期名称,格式化时间戳
      $formatter->setPattern('EEEE');
      $day_names[$n] = ucfirst($formatter->format($t));
  }
  
  $mes_pt = array('', 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro');

  // 替换原gmstrftime的多格式拼接,分别获取所需日期组件
  $formatter->setPattern('MM');
  $month = $formatter->format($first_of_month);

  $formatter->setPattern('yyyy');
  $year = $formatter->format($first_of_month);

  $formatter->setPattern('MMMM');
  $month_name = $formatter->format($first_of_month);

  // 转换星期格式:IntlDateFormatter的'e'模式返回周日=1,周六=7;gmstrftime的%w返回周日=0,周六=6
  $formatter->setPattern('e');
  $weekday = ($formatter->format($first_of_month) - 1) % 7;

  $title   = htmlentities(ucfirst($mes_pt[(int)$month])).'&nbsp;'.$year;

  @list($p, $pl) = each($pn); @list($n, $nl) = each($pn);
     if($p) $p = '<span class="calendar-prev">'.($pl ? '<a href="'.htmlspecialchars($pl).'">'.$p.'</a>' : $p).'</span>&nbsp;';
     if($n) $n = '&nbsp;<span class="calendar-next">'.($nl ? '<a href="'.htmlspecialchars($nl).'">'.$n.'</a>' : $n).'</span>';
     $calendar = '<table class="calendar">'."\n".
        '<caption class="calendar-month"><h1><center><strong>'.$p.($month_href ? '<a href="'.htmlspecialchars($month_href).'">'.$title.'</a>' : $title).$n."</strong></center></h1></caption>\n<tr>";

      if($day_name_length){ 

         $calendar .= "<th bgcolor='black'><center><strong style='color: #FFFFFF'>Domingo</strong></th>";
         $calendar .= "<th bgcolor='black'><center><strong style='color: #FFFFFF'>Segunda</strong></th>";
         $calendar .= "<th bgcolor='black'><center><strong style='color: #FFFFFF'>Terça</strong></th>";
         $calendar .=  "<th bgcolor='black'><center><strong style='color: #FFFFFF'>Quarta</strong></th>";
         $calendar .= "<th bgcolor='black'><center><strong style='color: #FFFFFF'>Quinta</strong></th>";
         $calendar .= "<th bgcolor='black'><center><strong style='color: #FFFFFF'>Sexta</strong></th>";
         $calendar .=  "<th bgcolor='black'><center><strong style='color: #FFFFFF'>Sábado</strong></th>";

         $calendar .= "</tr>\n<tr>";
       }
                                                
       if($weekday > 0) $calendar .= '<td colspan="'.$weekday.'">&nbsp;</td>';
}

注意事项

  • 确保PHP环境已启用intl扩展(这是使用IntlDateFormatter的必要条件)。
  • 若需适配巴西葡萄牙语,将IntlDateFormatter构造函数的第一个参数pt_PT改为pt_BR即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 11:54:54