PHP+MySQL实现跨重叠季节的房车租赁动态定价计算问题
问题解答
1. season_switch表日期存储方案
- 不需要保留年份,仅存
月-日格式(如04-01、08-31)即可,原因是季节规则每年通用,无需每年重复配置。如果后续有特殊年份需单独调整季节时间的需求,可额外增加年份字段做兼容。
2. 跨季节计价实现方案
核心逻辑优化
原有代码的问题主要有2点:
- 仅匹配了预订的头尾日期,没有遍历预订周期内的所有日期
- 日期对比逻辑没有剥离年份,无法每年复用季节规则
我们可以直接遍历预订周期内的所有日期匹配所属季节,统计对应天数后计算总价,不需要提前生成所有季节的日期数组,性能更高。
优化后可运行代码
<?php // 1. 读取季节配置,注意SQL里ORDER BY的字段不要加单引号,否则会按字符串常量排序出错 $sql = "SELECT * FROM season_switch ORDER BY id"; $result = $conn->query($sql); $seasonConfig = []; if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { // 把存储的日期统一转成月日格式,去掉年份 $startMmDd = date('m-d', strtotime($row['start_date'])); $endMmDd = date('m-d', strtotime($row['end_date'])); $seasonConfig[] = [ 'title' => $row['title'], 'value' => $row['title_value'], 'start_mmdd' => $startMmDd, 'end_mmdd' => $endMmDd ]; } } // 2. 处理用户预订日期,示例为2021-03-03到2021-05-06,可替换为用户实际提交的预订日期 $bookingStart = strtotime("2021-03-03"); $bookingEnd = strtotime("2021-05-06"); // 移除多余的+1天逻辑,此处+1是为了包含结束日,可根据你的实际入住计价规则调整 $bookingTotalDays = (int)(($bookingEnd - $bookingStart) / 86400) + 1; // 3. 初始化各季节天数统计,数组key和season_switch表的title_value对应即可 $seasonDays = [ 1 => 0, // 旺季 2 => 0, // 平季 3 => 0 // 淡季 ]; // 遍历预订周期内的每一天,匹配所属季节 for ($i = 0; $i < $bookingTotalDays; $i++) { $currentDate = strtotime("+$i day", $bookingStart); $currentMmDd = date('m-d', $currentDate); foreach ($seasonConfig as $season) { if ($currentMmDd >= $season['start_mmdd'] && $currentMmDd <= $season['end_mmdd']) { $seasonDays[$season['value']]++; break; } } } // 4. 查询用户选择的房车对应季节单价,此处示例房车id为1,可替换为实际选中的房车id $caravanId = 1; $sql = "SELECT low_season_price, mid_season_price, peak_season_price FROM caravan WHERE id_cvn = ?"; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $caravanId); $stmt->execute(); $caravan = $stmt->get_result()->fetch_assoc(); // 5. 计算总价,按title_value和单价映射即可 $totalPrice = 0; $totalPrice += $seasonDays[1] * $caravan['peak_season_price']; $totalPrice += $seasonDays[2] * $caravan['mid_season_price']; $totalPrice += $seasonDays[3] * $caravan['low_season_price']; // 结果验证,可根据业务需求调整输出逻辑 echo "旺季天数:" . $seasonDays[1] . "<br>"; echo "平季天数:" . $seasonDays[2] . "<br>"; echo "淡季天数:" . $seasonDays[3] . "<br>"; echo "总价格:" . $totalPrice; ?>
额外说明
如果后续季节规则调整为跨年(比如12月到次年2月为旺季),只需要在季节匹配逻辑中加一层跨年判断即可,现有逻辑支持所有非跨年的季节配置。
内容的提问来源于stack exchange,提问作者Timespider
相关产品推荐
相关产品推荐

