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

为何PHP中new DateTime('2012')会返回当前日期?

问题描述

我在PHP中遇到了一个奇特的行为,百思不得其解,不确定这是预期特性还是Bug,希望有人能解释其原因。

PHP的DateTime类通常能很好地解析多种格式的日期字符串:

echo (new DateTime('today'))->format('Y-m-d'); // 输出2024-08-15
echo (new DateTime('2012-02-18'))->format('Y-m-d'); // 输出2012-02-18
echo (new DateTime('2012-02'))->format('Y-m-d'); // 输出2012-02-01
echo (new DateTime('5 may'))->format('Y-m-d'); // 输出2024-05-05
echo (new DateTime('6 days ago'))->format('Y-m-d'); // 输出2024-08-09

但当仅传入年份时,却会返回当前日期:

echo (new DateTime('2012'))->format('Y-m-d'); // 输出2024-08-15

起初我以为传入无效日期或格式时会默认返回当前时间,但事实并非如此,以下情况均会抛出错误:

echo (new DateTime('fart'))->format('Y-m-d');
echo (new DateTime('1'))->format('Y-m-d');
echo (new DateTime('last may'))->format('Y-m-d');
echo (new DateTime('2012-02-48'))->format('Y-m-d');

为何传入单独年份会返回当前日期?根据其他情况的表现,我预期要么返回该年份的1月1日,要么抛出错误,但返回当前日期的选择非常奇怪。

(注:我并非寻求获取任意年份1月1日的方法,只是好奇PHP为何有此特殊行为。)


解答

这是PHP DateTime解析器的预期行为,而非Bug,核心逻辑如下:

  1. 格式匹配规则:
    PHP的DateTime依赖预定义的日期格式规则解析字符串,单独的四位数字(如"2012")不符合任何有效格式——标准年份格式需要搭配月、日(如YYYY-MM-DD)或至少月份(如YYYY-MM),单独的YYYY不属于预定义的部分日期格式。

  2. 错误判定逻辑:
    完全无意义的字符串(如"fart")、明显无效的日期(如"2012-02-48")或无法关联到任何日期组件的数字(如"1")会被判定为不可解析,因此抛出DateTimeException;但四位数字属于"看起来像日期组件但不完整"的输入,解析器不会直接报错。

  3. 回退机制:
    当解析器无法将字符串匹配为有效日期时,会回退到使用当前系统时间,这就是传入单独年份返回当前日期的原因。

补充说明

  • 像"2012-02"这样的YYYY-MM格式属于预定义的部分日期,解析器会自动补全日为01,因此返回2012-02-01。
  • 如果需要让单独的年份被解析为该年的1月1日,必须明确指定格式,例如:
    echo DateTime::createFromFormat('Y', '2012')->format('Y-m-d'); // 输出2012-01-01
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:43:10