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

CodeIgniter Datetime Picker筛选报format()调用bool类型错误

报错根因

抛出Exception: Call to a member function format() on bool的直接原因是代码对DateTime::createFromFormat()的返回值未做校验:该方法解析失败时会返回布尔值false,后续直接在返回值上调用format()方法就会触发致命错误。
具体触发逻辑对应你代码里的三个问题:

  • 控制器调用参数错误:你的数据库字段是DATETIME类型,前端Datetime Picker传的是带时间的字符串,但你调用to_sql_date()处理自定义查询范围的起止日期时,没有传入第二个参数$datetime = true,代码默认走纯日期解析分支。
  • 纯日期分支的解析逻辑不兼容带时间的输入:纯日期分支先用正则/^(\d{4})-(\d{1,2})-(\d{1,2})$/校验输入,带时间的字符串(比如2024-05-20 16:30、05/20/2024 2:30 PM)无法匹配该正则,后续代码拿仅配置了纯日期规则的$from_format去解析带时间的完整字符串,格式不匹配导致DateTime::createFromFormat()解析失败返回false,最终触发报错。
  • 传入不带时间的纯日期字符串时,要么能被正则直接匹配返回,要么和$from_format的纯日期规则匹配可以解析成功,所以功能运行正常。
可行修复方案

按以下步骤修改代码即可解决问题,同时补上容错逻辑避免后续同类报错:

  1. 修正控制器的函数调用参数
    找到get_where_report_period方法里自定义日期分支的两行调用,传入第二个参数开启datetime解析模式,同时优化范围查询逻辑避免漏数据,修改后代码如下:
} elseif ($months_report == 'custom') {
    // 第二个参数传true,走带时间的解析逻辑
    $from_date = to_sql_date($this->input->post('report_from'), true);
    $to_date   = to_sql_date($this->input->post('report_to'), true);

    // 范围查询优化:如果结束时间解析后是当天00:00:00,自动调整为当天23:59:59,避免漏掉当天的带时间数据
    if ($to_date && date('H:i:s', strtotime($to_date)) == '00:00:00') {
        $to_date = date('Y-m-d 23:59:59', strtotime($to_date));
    }

    if ($from_date == $to_date) {
        $custom_date_select = 'AND ' . $field . ' = "' . $this->db->escape_str($from_date) . '"';
    } else {
        $custom_date_select = 'AND (' . $field . ' BETWEEN "' . $this->db->escape_str($from_date) . '" AND "' . $this->db->escape_str($to_date) . '")';
    }
}
  1. 给to_sql_date函数的纯日期分支加解析容错
    找到$datetime == false分支里直接调用createFromFormat()->format()的代码段,替换为带校验和兼容逻辑的版本,避免解析失败直接报错:
// 原代码直接调用format的部分替换为以下内容
$dateObj = DateTime::createFromFormat($from_format, $date);
// 兼容意外传入带时间的字符串,自动截断取日期部分解析
if (!$dateObj && strpos($date, ' ') !== false) {
    $datePart = explode(' ', $date)[0];
    $dateObj = DateTime::createFromFormat($from_format, $datePart);
}
// 兜底解析:如果指定格式解析失败,用strtotime兼容常见日期格式
if (!$dateObj) {
    $parsedTs = strtotime($date);
    if ($parsedTs) {
        return hooks()->apply_filters('to_sql_date_formatted', date('Y-m-d', $parsedTs));
    }
    return null;
}
return hooks()->apply_filters(
    'to_sql_date_formatted',
    $dateObj->format($to_date)
);
  1. 给datetime分支加解析容错
    找到$datetime == true分支最后生成格式化时间的代码段,替换为带校验的版本:
// 原代码 $d = date('Y-m-d H:i:s', strtotime($date)); 替换为以下内容
$parsedTs = strtotime($date);
if (!$parsedTs) {
    $dateObj = DateTime::createFromFormat($from_format . ' H:i:s', $date);
    if (!$dateObj) {
        return null;
    }
    $d = $dateObj->format('Y-m-d H:i:s');
} else {
    $d = date('Y-m-d H:i:s', $parsedTs);
}
额外注意项

确认前端Datetime Picker输出的日期格式和后端get_current_date_format(true)返回的系统配置日期格式一致,避免因前后端格式不匹配导致解析异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:57:17