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

Doctrine按DateTime查询MySQL无结果且出现无限进程问题求助

问题解决步骤

1. 修复日期解析逻辑

你当前用的DateTime::createFromFormat格式无法正确匹配Vue返回的日期字符串,因为字符串包含GMT+0100和括号内的时区名称,格式符e+不适用。推荐两种更可靠的解析方式:

方式一:直接使用DateTime构造函数

PHP的DateTime原生支持解析这种标准日期字符串,无需指定格式:

// 直接解析Vue返回的日期字符串
$datetime = new DateTime($datas['date']);
// 切换到巴黎时区
$datetime->setTimezone(new DateTimeZone('Europe/Paris'));
// 设置时分秒为0
$datetime->setTime(0, 0, 0);

方式二:使用正确的格式符匹配

如果坚持用createFromFormat,需要匹配完整的字符串结构:

// 匹配带GMT和时区名称的格式
$format = 'D M d Y H:i:s \G\M\T O \(.*\)';
$datetime = DateTime::createFromFormat($format, $datas['date'], new DateTimeZone('Europe/Paris'));
if ($datetime) {
    $datetime->setTime(0, 0, 0);
} else {
    // 处理解析失败的情况,避免后续报错导致无限进程
    throw new \RuntimeException('日期解析失败');
}

2. 确保Doctrine查询的时区一致性

在Doctrine配置中,确保数据库连接的时区与Europe/Paris一致。可以在数据库URL中添加时区参数,或者在配置文件里设置:

# config/packages/doctrine.yaml 示例配置
doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
        server_version: '8.0'
        charset: utf8mb4
        timezone: 'Europe/Paris'

也可以在MySQL连接时执行SET time_zone = 'Europe/Paris';(优先用时区名称而非固定偏移,适配夏令时切换)。

3. 排查无限进程问题

无限进程大概率是因为日期解析失败(createFromFormat返回false),后续调用setTime触发致命错误,但错误处理不当导致程序循环重试。必须添加解析结果校验:

$datetime = DateTime::createFromFormat($format, $datas['date']);
if (!$datetime) {
    error_log('日期解析失败:' . $datas['date']);
    return new JsonResponse(['error' => '日期格式错误'], 400);
}

4. 验证查询生成的SQL

开启Doctrine的SQL日志,查看实际生成的查询语句,确认时间条件是否正确:

// 调试用:开启SQL日志
$this->em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
$projects = $this->em->getRepository(Project::class)->findBy(['release_date' => $datetime]);

正常生成的SQL应类似SELECT * FROM project WHERE p_release_date = '2023-03-24 00:00:00',若时区不匹配,会出现'2023-03-23 23:00:00'这类UTC时间,导致匹配失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 11:17:24