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

如何使用PHP的modify()方法仅设置DateTime的年份?

关于PHP DateTime::modify()仅修改年份的问题

根据PHP官方文档,理论上可以使用modify()方法仅修改DateTime的年份部分,但这仅对世纪部分为60-99的年份生效:

(new DateTime)->modify('1960')->format('c'); // '1960-01-25T19:09:44+00:00'

若年份的世纪部分为00-59(含),则会被解析为时间:

(new DateTime)->modify('1959')->format('c'); // '2024-01-25T19:59:00+00:00'

这情有可原,解析器无法区分用户输入的是日期还是时间。

如何强制解析器将输入识别为年份?根据复合格式的文档,字面量T应能区分输入的日期和时间部分,但测试后发现无效:

(new DateTime)->modify('1959T')->format('c'); // '2024-01-25T19:59:00+00:00'

仅指定T而无后缀并无效果。

尝试添加时间后缀的写法也不符合预期:

(new DateTime)->modify('1959T0000')->format('c'); // '0000-01-25T19:59:00+00:00'

原本以为设置年份时时间会自动设为午夜,但实际情况是:年份被设为0000,1959仍被当作时间。基于此,反转写法却能得到预期结果:

// 注意这里的空格可以和`T`互换
(new DateTime)->modify('0000 1959')->format('c'); // '1959-01-25T00:00:00+00:00'

这种写法确实有效(但会附带修改时间的副作用),但我们无法确定它理应生效(或未来仍能生效)——所有已文档化的有效复合格式中,时间从未出现在日期之前,为何反向指定反而可行?

尝试在日期后强制指定00:00作为时间会导致解析失败,因为解析器认为重复指定了时间:

(new DateTime)->modify('1959T00:00')->format('c');
(new DateTime)->modify('1959T00:00:00')->format('c');
// DateTime::modify(): Failed to parse time string (1959T00:00:00) at position 4 (T): Double time specification 

我了解已有关于仅设置年份的类似问题,但本文仅询问:是否存在仅使用modify()方法设置年份的正确写法?现有解决方案需重新显式设置月日,不够优雅且不应有此必要。

尽管'0000 1959'似乎是有效的年份设置方式,但存在两个可优化的点:

  • 该写法未被文档化,若有官方认可的实现方式则更佳
  • 当前写法会附带修改时间的副作用,若有仅修改年份的替代方案则更佳

此外,若有熟悉PHP内部实现的人士能解释为何'0000 1959'/'0000T1959'会按此方式解析(即时间在前、日期在后),这会十分有趣——这种行为自首次实现以来从未改变。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 17:22:44