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])).' '.$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> '; if($n) $n = ' <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.'"> </td>'; }
注意事项
- 确保PHP环境已启用intl扩展(这是使用
IntlDateFormatter的必要条件)。 - 若需适配巴西葡萄牙语,将
IntlDateFormatter构造函数的第一个参数pt_PT改为pt_BR即可。
内容的提问来源于stack exchange,提问作者Bruno
相关产品推荐
相关产品推荐

