
本文详解如何使用 PHP 的 date_sub() 函数对字符串形式的日期数组批量执行“减 1 年”操作,并修正常见类型错误导致的空输出问题。
本文详解如何使用 php 的 `date_sub()` 函数对字符串形式的日期数组批量执行“减 1 年”操作,并修正常见类型错误导致的空输出问题。
在 PHP 中,date_sub() 函数不能直接作用于字符串类型的日期(如 "2020-06-01"),它要求第一个参数是一个 DateTime 对象。原始代码中将字符串 $p 直接传入 date_sub(),因类型不匹配导致函数静默失败(无报错但无输出),这是初学者常见的典型误区。
正确做法是:先用 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 对象(关键!)
$dateTime = date_create($period);
// ✅ 步骤2:安全检查——避免创建失败(如非法日期)
if (!$dateTime) {
trigger_error("Invalid date format: '$period'", E_USER_WARNING);
continue;
}
// ✅ 步骤3:减去 1 年间隔
date_sub($dateTime, date_interval_create_from_date_string('1 year'));
// ✅ 步骤4:格式化输出
echo date_format($dateTime, 'Y-m-d') . '<br>';
}
输出结果:
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() 在遇到无效日期(如 '2023-02-30')时会返回 false,务必做空值校验;
- 使用 '1 year' 语义清晰,但注意:它按日历年计算(非固定 365 天),能自动处理闰年(如 2020-02-29 → 2019-02-28);
- 若需修改原数组而非仅输出,可使用引用遍历:foreach ($periods as &$period),并在循环内赋值 $period = date_format($dateTime, 'Y-m-d');;
- 更现代写法推荐使用 DateTimeImmutable(PHP 5.5+)避免意外修改对象状态:
$newPeriod = (new DateTime($period))->sub(new DateInterval('P1Y'))->format('Y-m-d');
掌握 DateTime 对象与字符串的正确转换逻辑,是安全、可靠处理日期运算的基础。











