PHP中strtotime跨年增减日期时出现计算错误
日期增减跨年错误的原因与解决方法
问题描述
我需要实现日期增减天数的功能,此前一直用以下PHP代码,平时运行正常,但年末跨年时出现错误:
date('o-m-d', strtotime("{$start_date} +6 days"));
正常场景示例:
date('o-m-d', strtotime("2022-12-19 +6 days")); // 输出2022-12-25,正确
错误场景:当增减后日期恰好为新年第一天时,年份计算错误:
date('o-m-d', strtotime("2022-12-26 +6 days")); // 输出2022-01-01,应为2023-01-01,错误!
更多测试案例:
// 加天数场景 date('o-m-d', strtotime("2022-12-30 +1 days")); // 2022-12-31,正确 date('o-m-d', strtotime("2022-12-30 +2 days")); // 2022-01-01,错误! date('o-m-d', strtotime("2022-12-30 +3 days")); // 2023-01-02,正确 // 减天数场景 date('o-m-d', strtotime("2023-01-03 -1 days")); // 2023-01-02,正确 date('o-m-d', strtotime("2023-01-03 -2 days")); // 2022-01-01,错误! date('o-m-d', strtotime("2023-01-03 -3 days")); // 2022-12-31,正确
尝试过添加时分秒、将基准日期作为strtotime第二个参数、使用DateTime类等方法,均出现相同错误:
$date = new \DateTime('2022-12-26'); $end_date = date_add($date, date_interval_create_from_date_string("6 days"))->format('o-m-d'); // 仍输出2022-01-01,错误
需求明确:2022-12-30加2天应得到2023-01-01,而非2022-01-01。
问题原因
错误根源在于你使用的日期格式符o:
o代表ISO-8601标准的年份,即日期所在周对应的年份,而非日期实际的公历年份。- 新年第一天(如2023-01-01)通常属于上一年的最后一周(比如2022年的第52/53周),因此
o会返回上一年的年份,导致年份与日期不匹配。
解决方案
将格式符中的o替换为Y即可,Y代表日期对应的公历4位年份,完全符合你的业务需求:
方案1:使用date() + strtotime()
date('Y-m-d', strtotime("2022-12-26 +6 days")); // 输出2023-01-01,正确
方案2:使用DateTime类(推荐)
$date = new \DateTime('2022-12-26'); $date->add(new \DateInterval('P6D')); // P6D表示6天的时间间隔 $end_date = $date->format('Y-m-d'); // 输出2023-01-01,正确
修正后测试验证:
date('Y-m-d', strtotime("2022-12-30 +2 days")); // 2023-01-01,正确 date('Y-m-d', strtotime("2023-01-03 -2 days")); // 2023-01-01,正确
内容的提问来源于stack exchange,提问作者John Beaven
相关产品推荐
相关产品推荐

