
本文详解如何正确使用 date_sub() 对字符串格式的日期数组(如 ['2020-06-01', '2020-07-01'])逐项减去 1 年,并输出标准化的 Y-m-d 格式结果,避免因类型错误导致无输出。
本文详解如何正确使用 `date_sub()` 对字符串格式的日期数组(如 `['2020-06-01', '2020-07-01']`)逐项减去 1 年,并输出标准化的 `y-m-d` 格式结果,避免因类型错误导致无输出。
在 PHP 中,date_sub() 函数不能直接操作字符串类型的日期(如 "2020-06-01"),它要求第一个参数必须是 DateTime 对象。原始代码中 $p 是字符串,调用 date_sub($p, ...) 会静默失败(不报错但无返回),因此没有任何输出。
✅ 正确做法是:对每个日期字符串先调用 date_create() 转换为 DateTime 对象,再执行 date_sub(),最后用 date_format() 格式化输出。
以下是完整、可运行的示例代码:
$periods = [
'2020-06-01', '2020-07-01', '2020-08-01', '2020-09-01',
'2021-01-01', '2022-01-01', '2022-06-01', '2022-08-01',
'2022-10-01', '2023-04-01'
];
foreach ($periods as $period) {
// ✅ 步骤1:将字符串转为 DateTime 对象
$dateObj = date_create($period);
// ✅ 步骤2:减去 1 年(自动处理闰年、月末等边界情况)
date_sub($dateObj, date_interval_create_from_date_string('1 year'));
// ✅ 步骤3:格式化输出
echo date_format($dateObj, 'Y-m-d') . '<br>';
}
? 输出结果(对应原数组每项减 1 年):
2019-06-01<br> 2019-07-01<br> 2019-08-01<br> 2019-09-01<br> 2020-01-01<br> 2021-01-01<br> 2021-06-01<br> 2021-08-01<br> 2021-10-01<br> 2022-04-01<br>
⚠️ 注意事项:
- date_create() 在输入非法日期时会返回 false,建议增加校验(如 if (!$dateObj) { throw new InvalidArgumentException("Invalid date: $period"); });
- date_interval_create_from_date_string('1 year') 是安全的,PHP 会智能处理跨闰年(如 2020-02-29 → 2019-02-28)和月末对齐(如 2021-03-31 → 2020-03-31,而非无效的 2020-02-31);
- 若需保留结果为新数组而非仅输出,可改用 $newPeriods[] = date_format($dateObj, 'Y-m-d');。
? 进阶提示:PHP 8.2+ 推荐使用面向对象风格(更清晰、支持方法链):
foreach ($periods as $period) {
echo (new DateTime($period))
->sub(new DateInterval('P1Y'))
->format('Y-m-d') . '<br>';
}
掌握 date_create() → date_sub() → date_format() 这一标准三步法,即可稳健处理任意日期数组的偏移运算。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











