PHP实现账单周期内折扣适用比例计算的通用函数需求
通用账单折扣比例计算PHP函数实现
需求说明
实现一个PHP函数,传入账单周期首尾日期、折扣起止日期,计算该账单周期内折扣的实际适用比例,支持百分比折扣和固定金额折扣两种场景:
- 百分比折扣:如90天50%折扣,账单周期重叠天数占比 × 50% 即为实际折扣比例
- 固定金额折扣:如90天100美元信用额度,账单周期重叠天数占比 × 100美元 即为该周期可使用的信用额度
示例场景:2023年3月账单周期为3月1日-3月31日(共31天),折扣为3月10日起生效的90天50%折扣,3月账单需适用约71%的50%折扣(即35.5%),4、5月适用全额50%折扣,6月适用约33%的50%折扣(即16.5%)。
函数实现
function applyDiscount(string $firstDay, string $lastDay, string $startDisc, string $endDisc): float { // 转换为DateTime对象,统一日期处理逻辑(可根据业务需求设置时区) $billStart = new DateTime($firstDay); $billEnd = new DateTime($lastDay); $discStart = new DateTime($startDisc); $discEnd = new DateTime($endDisc); // 计算账单周期总天数(包含首尾两天) $billTotalDays = $billStart->diff($billEnd)->days + 1; // 确定折扣与账单周期的重叠区间 $overlapStart = max($billStart, $discStart); $overlapEnd = min($billEnd, $discEnd); // 无重叠时返回0比例 if ($overlapStart > $overlapEnd) { return 0.0; } // 计算重叠天数(包含首尾两天) $overlapDays = $overlapStart->diff($overlapEnd)->days + 1; // 返回适用比例(保留4位小数,可按需调整精度) return round($overlapDays / $billTotalDays, 4); }
逻辑说明
- 日期标准化:用
DateTime类处理日期,避免手动解析字符串的错误,兼容多种合法日期格式。 - 天数计算:
diff()->days得到日期间隔天数,加1是为了包含周期首尾两天(如3月1日到3月2日实际为2天)。 - 重叠区间判定:通过
max和min精准定位折扣与账单周期的重叠部分,确保只计算实际覆盖的有效天数。 - 比例计算:重叠天数除以账单总天数,得到该周期内折扣的适用比例,返回浮点数便于后续业务计算。
测试用例与预期结果
// 3月账单:重叠天数22天,22/31≈0.7097 $discPercent = applyDiscount("2023-03-01","2023-03-31","2023-03-10","2023-06-10"); // 预期返回≈0.7097,实际折扣比例为0.7097×50%≈35.48% // 4月账单:全月在折扣期内,返回1.0 $discPercent = applyDiscount("2023-04-01","2023-04-30","2023-03-10","2023-06-10"); // 预期返回1.0 // 5月账单:全月在折扣期内,返回1.0 $discPercent = applyDiscount("2023-05-01","2023-05-31","2023-03-10","2023-06-10"); // 预期返回1.0 // 6月账单:重叠天数10天,10/30≈0.3333 $discPercent = applyDiscount("2023-06-01","2023-06-30","2023-03-10","2023-06-10"); // 预期返回≈0.3333
两种折扣类型的应用
- 百分比折扣:实际折扣比例 =
applyDiscount()返回值 × 折扣百分比(如50%折扣则乘0.5) - 固定金额折扣:该周期可用额度 =
applyDiscount()返回值 × 固定金额(如100美元信用额度则乘100)
内容的提问来源于stack exchange,提问作者rolinger
相关产品推荐
相关产品推荐

