一个纠结了很久的算法问题
传入参数:
$serverBeginDateTime:int(服务开始时间戳)
$serverEndDateTime:int(服务结束时间戳)
说明:
- 时间上均是未满一小时按一小时计算,向上取整。
- 边界性计价也是未满一小时按一小时计算,例如:订单总时长为4个小时,其中1.5个小时在正常使用,2.5小时在禁用时间段,则总时长应该为2小时为正常计价,3小时为惩戒性计价。
- 函数最终应该得出八个返回值,分别是:
-
- 总使用时长(精确到秒)
- 总使用计价(单位:分)
- 正常使用计价总时长(精确到秒)
- 正常计价总价(单位:分)
- 禁用时间段内使用总时长(精确到秒)
- 禁用时间段惩戒性计价(单位:分),
- 正常使用计价时间段(对象)
-
-
- 正常使用:(array)
-
-
-
-
- 开始时间
- 结束时间
- 该阶段收费
-
-
-
-
- 禁用时间段使用:(array)
-
-
-
-
- 开始时间
- 结束时间
- 该阶段收费(下面是例子)
-
-
{
"normal": [
{
"beginTime": "2024年11月3日 16:30:00",
"endTime": "2024年11月3日 21:29:59",
"amount": 25
},
{
"beginTime": "2024年11月4日 06:30:00",
"endTime": "2024年11月4日 21:29:59",
"amount": 30
},
{
"beginTime": "2024年11月5日 06:30:00",
"endTime": "2024年11月5日 21:29:59",
"amount": 30
}
],
"disable": [
{
"beginTime": "2024年11月3日 21:30:00",
"endTime": "2024年11月4日 06:29:59",
"amount": 90
},
{
"beginTime": "2024年11月4日 21:30:00",
"endTime": "2024年11月5日 06:29:59",
"amount": 90
},
{
"beginTime": "2024年11月5日 21:30:00",
"endTime": "2024年11月5日 23:15:00",
"amount": 20
}
]
}
条件:
- 如果存在禁用时间段(isDisableTime = true),则该笔订单禁用时间段期间的时间占用按照(fine)收费
-
- 禁用时间段总价=订单在禁用时间段内占用的时长总数(单位小时)*禁用时间段内使用收费价格
- 如果禁用结束时间(disableEndTime)小于禁用开始时间(disableStartTime),则代表存在跨凌晨的情况,代表是次日时间。
- 正常使用时间段内需要考虑几种情况:
-
- 循环周期内的封顶计价(capedPrice)
- 循环周期外的未达到下一个计价周期中封顶计价时的计价(overtimePrice)
- 订单不存在暂停的情况,只有开始和结束时间。
情况模拟:
假设参数列举如下:
-
- 计费周期(billingCycle)的值为 2(两小时计费一次)
- 单次计费周期收费价格(price)收费:每2小时 5元
- 单次计费周期内收费封顶价格(capedPrice):800分(8元)/2小时
- 单次计费周期外价格收费(overtimePrice):600分(6元)/小时
- 禁用时间段开始时间(disableStartTime)为:每天18:00
- 禁用时间段结束时间(disableEndTime)为:早上8:00(当disableEndTime > disableStartTime时,disableEndTime为次日)
- 禁用时间段(fine)内收费 1000分(10元)/小时
变量说明:
-
- n1 是计费周期内封顶价格的循环次数
- n2 是超出计费周期后每小时价格的循环次数
- n3 是禁用时间段内惩罚性计价的循环次数
1. 情况一(未占用禁用时间,且仅在一个计费周期内,未触及封顶价格):
-
- 订单于2024年11月1日 17:01:55开始
- 订单于2024年11月1日 17:26:26结束
- 计算公式:price * 1 = amout
2. 情况二(未占用禁用时间,且仅在一个计费周期内,有触及封顶价格):
-
- 订单于2024年11月1日 16:01:55开始
- 订单于2024年11月1日 17:26:26结束
- 计算公式:capedPrice * 1 = amout
3. 情况三(占用了一个禁用时间,且在一个计费周期内,未触及封顶价格):
-
- 订单于2024年11月1日 17:50:55开始
- 订单于2024年11月1日 18:56:26结束
- (price * 1)+(fine * 1) = amout
4. 情况四(占用了一个禁用时间,且在一个计费周期内,有触及封顶价格)
-
- 订单于2024年11月1日 16:50:55开始
- 订单于2024年11月1日 18:32:26结束
- (capedPrice * 1)+ (fine * 1) = amout
5. 情况五(未占用禁用时间,有多个计费周期,且超出的计费周期触及封顶价格)
-
- 订单于2024年11月1日 14:50:55开始
- 订单于2024年11月1日 17:45:32结束
- 计算公式:(capedPrice * n1) = amout
6. 情况六(未占用禁用时间,有多个计费周期,且超出的计费周期未满封顶价格)
-
- 订单于2024年11月1日 15:50:55开始
- 订单于2024年11月1日 17:56:32结束
- 计算公式:(capedPrice * n1) + (overtimePrice * 1) = amoutfine
7. 情况七(占用了一个禁用时间,有多个计费周期,且超出的计费周期触及满封顶价格)
-
- 订单于2024年11月1日 14:50:55开始
- 订单于2024年11月1日 18:45:32结束
- 计算公式:(capedPrice * n1) + (overtimePrice * n2)+ (fine * 1)= amout
8. 情况八(占用了一个禁用时间,有多个计费周期,且超出的计费周期未满封顶价格)
-
- 订单于2024年11月1日 13:50:55开始
- 订单于2024年11月1日 17:55:32结束
- 计算公式:(capedPrice * n1) + (overtimePrice * 1)+ (fine * 1)= amout
9. 情况九(占用了多个禁用时间,有多个计费周期,且超出的计费周期触及满封顶价格)
-
- 订单于2024年11月1日 14:50:55开始
- 订单于2024年11月5日 18:45:32结束
- 计算公式:(capedPrice * n1) + (fine * n3)= amout
10. 情况十(占用了多个禁用时间,有多个计费周期,且超出的计费周期未满封顶价格有多个)
-
- 订单于2024年11月1日 14:50:55开始
- 订单于2024年11月4日 17:55:32结束
- 计算公式:(capedPrice * n1) + (overtimePrice * n2)+ (fine * n3)= amout