我有一个预订系统,用户可以在该系统中随时预订房间,连续预订任意天数。预订费用根据房间使用的分钟数而定。
在预订系统中,开始和结束时间由两个时间戳表示。例如
start_time = 1397124000
end_time = 1397129400
由此,我可以计算预订的秒数,从而计算费用。
我遇到的问题是,我想计算出在高峰时段(上午8点之前和下午6点之后)预订的50%折扣。预订可以在这些时间进行(即早上7点至9点),因此应该打折适当的比例(上午7点至7点预订的7点至8点部分可以打折50%)。
我的计算代码变得非常混乱和复杂,因为有几个场景:
- 预订在折扣期内开始和结束(例如,凌晨3点至7点-折扣4小时)
- 预订在折扣期间开始,但在折扣之后结束(例如上午7点至上午9点-折扣1小时)
- 预订开始和结束时间为非折扣期(上午10点至下午5点-无折扣)
- 预订在一段不打折的时间内开始,但在之后结束(下午5点至10点-打折1小时)
- 预订时间跨度为整个前后折扣期(凌晨2点至晚上10点折扣10小时),甚至更复杂(第1天凌晨2点到第5天晚上10点,折扣50小时)
目前,当只提供开始和结束时间戳时,很难计算出在上午8点之前和下午6点之后的折扣期内预订的比例。
我的代码是一系列非常大的if
和else
语句,它们针对开始和结束时间进行测试,但对于超过一天的预订,它并不健壮,而且在其他方面非常混乱。
我正在寻找一种方法,可以很容易地计算折扣时间内预订的比例,并考虑到所有可能的情况。一个难题!
在思考了许多选项后,我最终想到了以下解决方案。
我写了一个函数,以30分钟的间隔浏览预订的开始和结束时间,检查每次是否在折扣期内:
function discount_period($timestamp) {
$lowerTime = mktime (8,0,0,date("n", $timestamp), date("j", $timestamp), date("Y", $timestamp));
$upperTime = mktime (18,0,0,date("n", $timestamp), date("j", $timestamp), date("Y", $timestamp));
if (($timestamp < $lowerTime) || ($timestamp >= $upperTime)) {
return true;
}
else {
return false;
}
}
$discountmins = 0;
$nondiscountmins = 0;
for ($i = strtotime($billingResult->start_time); $i < strtotime($billingResult->end_time); $i += 1800) {
if (discount_period($i)) {
// This is within a discount period of at least 30 minutes
$discountmins += 30;
}
else {
$nondiscountmins +=30;
}
}
$discountedcost = ((($discountmins / 60) * $billingResult->cost_per_hr) * 0.5) / 100;
$nondiscountcost = (($nondiscountmins / 60) * $billingResult->cost_per_hr) / 100;
因此,它本质上是检查下一个30分钟窗口是否在折扣期内——如果是,它会增加折扣分钟计数器,如果不是,则增加非折扣分钟计数器。最后,他们只是根据分钟数来计算成本。