PHP DateTime循环:如何从指定日期遍历至当前日期(不含当日)
为什么PHP DateTime循环中用
<仍会包含当前日期?如何解决? 问题原因
核心问题在于DateTime对象存储的是完整的日期+时间信息,而非单纯的日期:
- 你的
$date_begin是2005-03-11,默认时间为00:00:00,每次执行modify("+1 day")后,$i的时间始终保持当天的00:00:00。 - 而
$today = new DateTime("now")会获取当前的完整时间(比如2024-05-20 16:40:00)。 - 当
$i走到当前日期的00:00:00时,和$today的完整时间对比,00:00:00 < 16:40:00的结果为true,因此会进入循环,导致当前日期被包含。
你的误解
你误以为DateTime对象的比较只针对日期部分,但实际上PHP是基于完整的时间戳(包含时分秒)进行对比的,只要前者的时间戳更小,<条件就会成立。
正确解决方法
这里提供三种实用方案:
方案1:将$today重置为当天凌晨0点
把$today的时间部分设为00:00:00,这样对比时就是纯日期的比较:
$date_begin = new DateTime("2005-03-11"); $today = new DateTime("today"); // 等价于 new DateTime("now")->setTime(0, 0, 0) for ($i = $date_begin; $i < $today; $i->modify("+1 day")) { // 执行你的业务逻辑 echo $i->format('Y-m-d') . PHP_EOL; }
方案2:循环中仅对比日期字符串
如果不想修改$today,可以在循环条件中只比较日期的字符串形式:
$date_begin = new DateTime("2005-03-11"); $today = new DateTime("now"); for ($i = $date_begin; $i->format('Y-m-d') < $today->format('Y-m-d'); $i->modify("+1 day")) { // 执行你的业务逻辑 echo $i->format('Y-m-d') . PHP_EOL; }
方案3:用DatePeriod优雅生成日期范围
PHP的DatePeriod专门用于处理日期范围遍历,代码更简洁易维护:
$date_begin = new DateTime("2005-03-11"); $today = new DateTime("today"); // 当天0点,作为范围的结束(不包含) $interval = new DateInterval('P1D'); // 定义间隔为1天 $period = new DatePeriod($date_begin, $interval, $today); foreach ($period as $date) { // 执行你的业务逻辑 echo $date->format('Y-m-d') . PHP_EOL; }
这个方法会自动生成从起始日期到结束日期(不包含)的所有日期,无需手动控制循环条件。
内容的提问来源于stack exchange,提问作者Wolfhart
相关产品推荐
相关产品推荐

