PHP如何实现从复活节日期中减去一周?
问题原因
你遇到的结果错位,是冗余操作叠加解析规则冲突导致的,和减7天的计算逻辑本身无关,根本不存在代码主动扣减年份的情况:
- 函数使用绕了弯路:
easter_date()本身返回的就是指定年份复活节对应的Unix时间戳,完全没必要先把这个时间戳用date()转成不带世纪的日期字符串,再把这个字符串丢回strtotime()重新转回时间戳。 - 解析规则错配:你格式化出来的复活节字符串是
04-04-21,对应的是你自定义的「日-月-两位年」顺序。但PHP的strtotime()对短横-分隔的纯数字日期,默认会按照ISO 8601的「年-月-日」顺序解析,不会匹配你的自定义格式。相当于它把04-04-21认成了2004年4月21日,在这个错误的时间点上减7天,自然就得到了2004年4月14日,格式化后就是你看到的14-04-04,和2021年的复活节没有任何关系。 - 输出逻辑的bug:
strtotime()返回的是整数类型的Unix时间戳,不是格式化的日期字符串,直接echo本来应该输出一串数字时间值,你能看到格式化后的日期,大概率是后续流程里对这个错误解析的时间戳做了二次格式化。
正确实现
完全不需要绕字符串转换的弯路,直接基于easter_date()返回的原生时间戳计算即可:
<?php $year = date("Y"); // 直接获取复活节的原生时间戳 $easterTs = easter_date($year); // 直接基于这个时间戳计算减7天的偏移 $beforeEasterTs = strtotime('-7 days', $easterTs); // 最后统一格式化输出 $easterdate = date('d-m-y', $easterTs); $newdate = date('d-m-y', $beforeEasterTs); ?> <body> <?php echo $newdate;?> <br> <?php echo $easterdate;?> <br> </body>
如果涉及跨时区、夏令时切换的场景,更稳妥的写法是用DateTime类处理,从根源上避免字符串解析的坑:
<?php $year = date("Y"); $easter = (new DateTime())->setTimestamp(easter_date($year)); // 克隆实例避免修改原对象 $beforeEaster = (clone $easter)->modify('-7 days'); echo $beforeEaster->format('d-m-y') . '<br>'; echo $easter->format('d-m-y') . '<br>'; ?>
避坑提示
- 传给
strtotime()的日期字符串尽量带4位完整年份,不要用不带世纪的两位年,减少解析错位的概率。 - 如果需要使用「日-月-年」这类非标准顺序的日期格式,不要直接丢给
strtotime()自动猜格式,优先用DateTime::createFromFormat()按照你定义的规则手动解析。
内容的提问来源于stack exchange,提问作者Andrew H
相关产品推荐
相关产品推荐

