You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中比较m-d与y-m-d格式日期及计算区间天数的方法

PHP场景下m-d格式与完整Y-m-d日期比较、区间统计最优方案

核心实现思路

  • 优先使用PHP原生DateTime、DatePeriod类处理日期逻辑,规避手动计算时间戳、拼接日期带来的闰年、月份天数差、时区等误差
  • 不需要给仅含月日的季节起止日期补全年份,遍历日期区间时将每个日期格式化为m-d字符串,直接和季节起止字符串做字典序比较即可——固定两位月+两位日的m-d格式,字典序和实际日期先后顺序完全一致
  • 逻辑兼容两种季节区间场景:季节起止在同一年(如示例的03-15到04-30)、季节区间跨年度(如12-15到次年01-20)
  • 自动校正输入的两个完整日期的先后顺序,不需要提前判断$date1、$date2哪个更早

可直接复用的实现代码

// 示例输入参数
$date1 = "2022-04-20";
$date2 = "2022-05-20";
$seasonStart = "03-15";
$seasonEnd = "04-30";

// 初始化完整日期区间端点
$startDate = new DateTime($date1);
$endDate = new DateTime($date2);
// 校正顺序,保证左端点早于右端点
if ($startDate > $endDate) {
    [$startDate, $endDate] = [$endDate, $startDate];
}
// DatePeriod的结束日期为排他逻辑,加1天保证包含区间最后一天
$endDate = $endDate->modify('+1 day');

// 判断季节区间是否跨年
$isCrossYearSeason = $seasonStart > $seasonEnd;
$matchCount = 0;

// 按天遍历整个日期区间
$period = new DatePeriod($startDate, new DateInterval('P1D'), $endDate);
foreach ($period as $currentDay) {
    $currentMd = $currentDay->format('m-d');
    if ($isCrossYearSeason) {
        // 跨年季节区间:月日大于等于起始值 或 小于等于结束值 即为命中
        if ($currentMd >= $seasonStart || $currentMd <= $seasonEnd) {
            $matchCount++;
        }
    } else {
        // 同年季节区间:月日介于起止值之间 即为命中
        if ($currentMd >= $seasonStart && $currentMd <= $seasonEnd) {
            $matchCount++;
        }
    }
}

echo $matchCount; // 示例场景输出11,即4月20日-4月30日共11天符合要求

避坑说明

不要给m-d格式的日期拼接当年年份再转时间戳比较:如果遇到平年,拼接2月29日会生成无效日期导致判断失效;如果遇到跨年的季节区间,拼接单一年份会完全算错后半段的日期范围。
不要手动拆分月、日做数字比较:需要额外写逻辑处理不同月份的天数差、闰年2月的特殊情况,代码冗余且容易出边界bug。

内容的提问来源于stack exchange,提问作者A. Atal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:03:25