/// <summary>
 /// 计算两个时段内的收费费用,不考虑时段的最高收费
 /// </summary>
 /// <param name="beginning"></param>
 /// <param name="ending"></param>
 /// <returns></returns>
 private TariffTwoZoneCharge CalculateTwoZoneChargeFee(DateTime beginning, DateTime ending)
 {
     TariffTwoZoneCharge chargeFee = new TariffTwoZoneCharge(beginning, ending);
     double minDay = 0;
     double minNight = 0;
     //交替计算,直到所有时段都计算完
     do
     {
         minDay = DayTimezone.SliceDuration(beginning, ending, SwitchWhenTimeZoneOverTime);
         if (minDay > 0)
         {
             chargeFee.FirstCharge += DayTimezone.CalculateFeeWithOutLimiteFee(minDay);
             beginning = beginning.AddMinutes(minDay);
         }
         minNight = NightTimezone.SliceDuration(beginning, ending, SwitchWhenTimeZoneOverTime);
         if (minNight > 0)
         {
             chargeFee.SecondCharge += NightTimezone.CalculateFeeWithOutLimiteFee(minNight);
             beginning = beginning.AddMinutes(minNight);
         }
     }
     while (minDay > 0 || minNight > 0);
     return chargeFee;
 }
        /// <summary>
        /// 计算时段内的优惠金额,计算的时段不超过24小时
        /// </summary>
        /// <param name="beginning">时段的开始时间</param>
        /// <param name="ending">时段的结算时间</param>
        /// <param name="discountHour">可用的优惠时数</param>
        /// <param name="currentHour">输出:当前使用的优惠时数</param>
        /// <returns></returns>
        private decimal CalculateDiscountMoneyTimeZone(DateTime beginning, DateTime ending, int discountHour, out int currentHour)
        {
            decimal discountFee = 0;
            currentHour = 0;
            if (discountHour <= 0) return discountFee;//如果优惠时数小于等于0,优惠金额为0
            TimeSpan ts = new TimeSpan(ending.Ticks - beginning.Ticks);
            int totalParkingHour = (int)Math.Ceiling(ts.TotalHours);//总共停车时长(整数,不足一小时按一小时计)

            //如果优惠时数大于等于停车时长,优惠金额为时段收取的费用,当前使用的优惠时数为停车时长
            if (discountHour >= totalParkingHour)
            {
                currentHour = totalParkingHour;
                discountFee = CalculateFeeAlteration(beginning, ending);
                return discountFee;
            }

            currentHour = discountHour;//当前使用的优惠时数为可用的优惠时数
            int workHour = currentHour;

            #region 时间段算出每小时收取的费用集合
            DateTime moveBegin = beginning;//定义可变的开始时间
            DateTime moveEnd = ending;     //定义可变的结束时间
            List<TariffTwoZoneCharge> moveAreaMoneyList = new List<TariffTwoZoneCharge>();//定义每过一个小时的时间片段费用的集合
            for (int i = 0; i < totalParkingHour; i++)
            {
                DateTime calMoveEnd = moveBegin.AddHours(1);
                calMoveEnd = calMoveEnd >= moveEnd ? moveEnd : calMoveEnd;
                TariffTwoZoneCharge areaHourMoney = CalculateTwoZoneChargeFee(moveBegin, calMoveEnd);
                moveAreaMoneyList.Add(areaHourMoney);//将此一小时的费用加入费用片段集合
                moveBegin = moveBegin.AddHours(1);
            }
            #endregion

            //decimal chargFee = moveAreaMoneyList.Sum(c => c.ChargeFee);//定义时间段内应收的费用
            //decimal chargFee = CalculateFeeAlteration(beginning, ending);//定义时间段内应收的费用
            TariffTwoZoneCharge chargMoney = CalculateTwoZoneChargeFee(beginning, ending);//定义时间段内应收的费用

            #region 获取待优惠的费用集合
            List<TariffTwoZoneCharge> discountMoneyList = new List<TariffTwoZoneCharge>();//定义用于优惠的时间段费用

            //根据优惠时数循环获取最大的时间段费用作为优惠的费用
            do
            {
                TariffTwoZoneCharge maxAnHourMoney = moveAreaMoneyList.Max();
                discountMoneyList.Add(maxAnHourMoney);

                moveAreaMoneyList.Remove(maxAnHourMoney);
                workHour -= 1;
            }
            while (workHour > 0);
            #endregion


            decimal dayDiscount = discountMoneyList.Sum(c => c.FirstCharge);//定义日间时段优惠的费用
            decimal nightDiscount = discountMoneyList.Sum(c => c.SecondCharge);//定义夜间时段优惠的费用
            //decimal dayFee = moveAreaMoneyList.Sum(c => c.FirstCharge);//定义优惠后日间还需收取的费用
            decimal nightFee = moveAreaMoneyList.Sum(c => c.SecondCharge);//定义优惠后夜间还需收取的费用
            decimal dayFee = chargMoney.FirstCharge - dayDiscount;//定义优惠后日间还需收取的费用,因为日间没有最高收费,所以这里直接使用日间费用-优惠费用
            if (nightFee < chargMoney.SecondCharge - nightDiscount)
            {
                //如果优惠后夜间还需收取的费用小于夜间应收费用-夜间优惠费率
                nightFee = chargMoney.SecondCharge - nightDiscount;//优惠后夜间还需收取的费用为夜间应收费用-夜间优惠费率
            }
            if (dayFee < 0)
            {
                //如果定义优惠后日间还需收取的费用为负数,日间优惠的费用为日间时段的费用
                dayFee = 0;
                dayDiscount = chargMoney.FirstCharge;
            }
            if (nightFee < 0)
            {
                //如果定义优惠后夜间还需收取的费用为负数,夜间优惠的费用为夜间时段的费用
                nightFee = 0;
                nightDiscount = chargMoney.SecondCharge;
            }

            #region 夜间最高限额判断
            //如果夜间有最高限价,不管夜间有没有优惠费用,都需要进行最高限价判断
            if (NightTimezone.LimiteFee != null && NightTimezone.LimiteFee.Value > 0)
            {
                //先判断优惠后夜间收取的费用是否大于等于最高限额
                if (nightFee >= NightTimezone.LimiteFee.Value)
                {
                    //大于等于最高限额,夜间优惠金额设为0,优惠后夜间还需收取的费用为最高限额
                    nightDiscount = 0;
                    nightFee = NightTimezone.LimiteFee.Value;
                }
                else
                {
                    //小于最高限额的,需判断原来的夜间收费是否大于最高限额
                    if (nightFee + nightDiscount > NightTimezone.LimiteFee.Value)
                    {
                        //原来的夜间收费大于最高限额的,夜间优惠金额为最高限额-优惠后夜间收取费用
                        nightDiscount = NightTimezone.LimiteFee.Value - nightFee;
                    }
                }
            }
            #endregion

            //优惠金额为夜间优惠金额+日间优惠金额
            discountFee = nightDiscount + dayDiscount;

            #region 24小时最高收费判断
            if (FeeOf24Hour > 0)
            {
                //先判断优惠后的时段收费是否大于等于24小时最高收费
                //if (chargFee - discountFee >= FeeOf24Hour)
                if (dayFee + nightFee >= FeeOf24Hour)
                {
                    //优惠后的时段收费大于等于24小时最高收费的,优惠金额为0
                    discountFee = 0;
                }
                else
                {
                    //小于24小时最高收费,需判读原来的时段收费是否大于24小时最高收费
                    //if (chargFee > FeeOf24Hour)
                    if (chargMoney.ChargeFee > FeeOf24Hour)
                    {
                        //原来的时段收费大于24小时最高收费的,优惠金额为24小时最高收费-优惠后收取的费用
                        //discountFee = FeeOf24Hour - (chargFee - discountFee);
                        discountFee = FeeOf24Hour - (dayFee + nightFee);
                    }
                }
            }
            #endregion

            //如果出现负数,设优惠金额为0
            if (discountFee < 0)
            {
                discountFee = 0;
            }
            return discountFee;
        }