C# 时段计费算法

留点什么?希望别人有用……
一天分成多个时间段,各个时段不同的费用,以前在小软件上有做个类似的,但现在发觉之前的方法还是有点小问题了,
而今无聊之余,重新整理思绪,算是做了些优化吧

源码:https://download.csdn.net/download/wysdong/10883293 (源码加上去,就不能删!~,所有源码的类CalcM,还是用文章后面的吧)

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CLib
{
    public class CalcM
    {

  public CalcM()
        {

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="_FreeMinute">免费停车 分钟</param>
        /// <param name="_iMinTime">最低消费时间长</param>
        /// <param name="_oneDayMaxCost">一天最高的费用</param>
        /// <param name="_timelist">时间段&每小时费用  _timelist.Add("00:00&08:00&4");//起始时间&结束时间&费率</param>
        /// <param name="_idayType">一整天计费方式:0=汇总各个时段费用(时段长*单价);1=用“idayMoney一整天的费用”来计算;2=重新计算,按firstHour内多少钱,后面各个小时多少钱</param>
        /// <param name="_idayMoney">一整天的费用</param>
        /// <param name="_iFirstType">0=前N分钟不计费,1=最低扣费时间长</param>
        /// <param name="_firstHour">超过免费时间后,firstHour小时内FirstCash元</param>
        /// <param name="_firstCash">超过免费时间后,firstHour小时内FirstCash元</param>
        /// <param name="_iAfter24H">第二天(过晚上24点后),计费方式:0=重新计费,1=汇总各时段费用</param>
        public CalcM(int _FreeMinute, int _iMinTime, decimal _oneDayMaxCost, System.Collections.ArrayList _timelist,
            int _idayType, decimal _idayMoney, int _iFirstType, int _firstHour, int _firstCash, int _iAfter24H)
        {
            this.FreeMinute = _FreeMinute;
            this.iMinTime = _iMinTime;
            this.OneDayMaxCost = _oneDayMaxCost;
            this.timelist = _timelist;
            this.idayType = _idayType;
            this.idayMoney = _idayMoney;
            this.iFirstType = _iFirstType;
            this.firstHour = _firstHour;
            this.firstCash = _firstCash;
            this.iAfter24H = _iAfter24H;
        }


        #region 计费参数

        /// <summary>
        /// 免费停车 分钟
        /// </summary>
        private int _FreeMinute = 30;
        /// <summary>
        /// 最低消费时间长
        /// </summary>
        private int _iMinTime = 30;
        /// <summary>
        /// 一天最高的费用
        /// </summary>
        private decimal _oneDayMaxCost = 99999990;
        /// <summary>
        ///  时间段&每小时费用  _timelist.Add("00:00&08:00&4");//起始时间&结束时间&费率
        ///   _timelist.Add("00:00&08:00&4");
        ///   _timelist.Add("08:00&16:00&5");
        ///   _timelist.Add("16:00&23:59&6");
        /// </summary>
        private System.Collections.ArrayList _timelist = new ArrayList();
        /// <summary>
        /// 一整天计费方式:0=汇总各个时段费用(时段长*单价);1=用“idayMoney一整天的费用”来计算;2=重新计算,按firstHour内多少钱,后面各个小时多少钱
        /// </summary>
        private int _idayType = 0;
        /// <summary>
        /// 一整天的费用
        /// </summary>
        private decimal _idayMoney = 60;
        /// <summary>
        ///  0=前N分钟不计费,1=最低扣费时间长
        /// </summary>
        private int _iFirstType = 0;
        /// <summary>
        /// 超过免费时间后,firstHour小时内FirstCash元
        /// </summary>
        private int _firstHour = 3;
        /// <summary>
        /// 超过免费时间后,firstHour小时内FirstCash元
        /// </summary>
        private int _firstCash = 10;
        /// <summary>
        /// 第二天(过晚上24点后),计费方式:0=重新计费,1=汇总各时段费用
        /// </summary>
        private int _iAfter24H = 0;

        /// <summary>
        /// 免费停车 分钟
        /// </summary>
        public int FreeMinute
        {
            get
            {
                return _FreeMinute;
            }
            set
            {
                _FreeMinute = value;
            }
        }


        /// <summary>
        /// 单天最高的费用
        /// </summary>
        public decimal OneDayMaxCost
        {
            get
            {
                return _oneDayMaxCost;
            }

            set
            {
                _oneDayMaxCost = value;
            }
        }

        /// <summary>
        /// 时间段&每小时费用  _timelist.Add("00:00&08:00&4");
        /// </summary>
        public ArrayList timelist
        {
            get
            {
                if (_timelist.Count < 1)
                {
                    _timelist.Add("00:00&08:00&4");
                    _timelist.Add("08:00&16:00&5");
                    _timelist.Add("16:00&23:59&6");
                }
                return _timelist;
            }
            set
            {
                _timelist = value;
            }
        }

        /// <summary>
        /// 一整天计费方式:0=汇总各个时段费用(时段长*单价);1=用“idayMoney一整天的费用”来计算;2=重新计算,按firstHour内多少钱,后面各个小时多少钱
        /// </summary>
        public int idayType
        {
            get
            {
                return _idayType;
            }

            set
            {
                _idayType = value;
            }
        }

        /// <summary>
        /// 一整天的费用
        /// </summary>
        public decimal idayMoney
        {
            get
            {
                return _idayMoney;
            }
            set
            {
                _idayMoney = value;
            }
        }

        /// <summary>
        /// 最低消费时间长
        /// </summary>
        public int iMinTime
        {
            get
            {
                return _iMinTime;
            }

            set
            {
                _iMinTime = value;
            }
        }
        /// <summary>
        /// 0=前N分钟不计费,1=最低扣费时间长
        /// </summary>
        public int iFirstType
        {
            get
            {
                return _iFirstType;
            }

            set
            {
                _iFirstType = value;
            }
        }

        /// <summary>
        /// 超过免费时间后,firstHour小时内FirstCash元
        /// </summary>
        public int firstHour
        {
            get
            {
                return _firstHour;
            }

            set
            {
                _firstHour = value;
            }
        }

        /// <summary>
        /// 超过免费时间后,firstHour小时内FirstCash元
        /// </summary>
        public int firstCash
        {
            get
            {
                return _firstCash;
            }

            set
            {
                _firstCash = value;
            }
        }
        /// <summary>
        /// 第二天(过晚上24点后),计费方式:0=重新计费,1=汇总各时段费用
        /// </summary>
        public int iAfter24H
        {
            get
            {
                return _iAfter24H;
            }

            set
            {
                _iAfter24H = value;
            }
        }


        #endregion

        #region 计算费用
        int iDayIndex = 1;
        /// <summary>
        /// 计算费用
        /// </summary>
        /// <param name="ST">起始时间</param>
        /// <param name="OT">停止时间</param>
        /// <returns></returns>
        public string CalcStopCash(DateTime ST, DateTime OT)
        {
            backdata rt = new backdata();
            rt.result = "OK";
            rt.errcode = "0";
            rt.errmsg = "";
            rt.paycash = 0;
            rt.iHour = 0;
            decimal _CalcM = 0;
            string result = "";
            string errmsg = "";
            ArrayList alist = new ArrayList();
            iDayIndex = 1;
            string StopTimeInfo = "";
            try
            {

                #region 
                if (decimal.Parse(ST.ToString("yyMMddHHmm")) >= decimal.Parse(OT.ToString("yyMMddHHmm")))
                {
                    rt.result = "FAIL";
                    rt.errcode = "-1";
                    rt.errmsg = "停车的起始时间>=截止时间,无法计算。";
                    result = Newtonsoft.Json.JsonConvert.SerializeObject(rt);
                    return result;
                }
                TimeSpan ts = OT.Subtract(ST);
                rt.iHour = decimal.Parse(ts.TotalHours.ToString("f2"));
                if (ts.Days > 0)
                {
                    StopTimeInfo += ts.Days.ToString() + "天";
                }
                if (ts.Hours > 0)
                {
                    StopTimeInfo += ts.Hours.ToString() + "小时";
                }
                if (ts.Minutes > 0)
                {
                    StopTimeInfo += ts.Minutes.ToString() + "分钟";
                }
                #endregion
                DateTime _ST = ST;
                DateTime _OT = OT;
                while (decimal.Parse(_ST.ToString("yyMMdd")) <= decimal.Parse(_OT.ToString("yyMMdd")))
                {
                    decimal OneDayCash = 0;//计算某一天的费用
                    if (ST.ToString("yyMMdd") == OT.ToString("yyMMdd"))
                    {
                        OneDayCash = CalcOneDayCast(ST, OT, ref alist, true);
                        if (OneDayCash == -100)
                        {
                            rt.result = "FAIL";
                            rt.errcode = "-2";
                            rt.errmsg = "计费出错:" + ExceptionInfo;
                            result = Newtonsoft.Json.JsonConvert.SerializeObject(rt);
                            return result;
                        }
                        _CalcM += OneDayCash;
                    }
                    else
                    {
                        #region
                        if (_ST.ToString("yyMMdd") == ST.ToString("yyMMdd"))
                        {
                            #region 起始一天

                            DateTime _temDT = DateTime.Parse(_ST.ToString("yyyy-MM-dd 23:59:59"));
                            OneDayCash = CalcOneDayCast(ST, _temDT, ref alist, true);
                            if (OneDayCash == -100)
                            {
                                rt.result = "FAIL";
                                rt.errcode = "-3";
                                rt.errmsg = "计费出错:" + ExceptionInfo;
                                result = Newtonsoft.Json.JsonConvert.SerializeObject(rt);
                                return result;
                            }
                            _CalcM += OneDayCash;


                            #endregion
                        }
                        else if (_ST.ToString("yyMMdd") == OT.ToString("yyMMdd"))
                        {

                            #region 最后一天
                            DateTime _temDT = DateTime.Parse(_ST.ToString("yyyy-MM-dd 00:00:00"));
                            OneDayCash = CalcOneDayCast(_temDT, OT, ref alist, false);
                            if (OneDayCash == -100)
                            {
                                rt.result = "FAIL";
                                rt.errcode = "-4";
                                rt.errmsg = "计费出错:" + ExceptionInfo;
                                result = Newtonsoft.Json.JsonConvert.SerializeObject(rt);
                                return result;
                            }
                            _CalcM += OneDayCash;

                            #endregion
                        }
                        else
                        {
                            #region  一整天

                            if (idayType == 2)
                            {
                                //errmsg = "超过1天,按收费标准重新计费:";
                                //重新按计费标准计费
                                DateTime tem_beg = DateTime.Parse(_ST.ToString("yyyy-MM-dd 00:00:00"));
                                DateTime tem_end = DateTime.Parse(_ST.ToString("yyyy-MM-dd 23:59:00"));
                                OneDayCash = CalcOneDayCast(tem_beg, tem_end, ref alist, false);
                                if (OneDayCash == -100)
                                {
                                    rt.result = "FAIL";
                                    rt.errcode = "-5";
                                    rt.errmsg = "计费出错:" + ExceptionInfo;
                                    result = Newtonsoft.Json.JsonConvert.SerializeObject(rt);
                                    return result;
                                }
                            }
                            else
                            {
                                OneDayCash = idayMoney;
                                if (OneDayCash > OneDayMaxCost)
                                {
                                    OneDayCash = OneDayMaxCost;
                                    errmsg = "------>:" + iDayIndex.ToString() + "、" + _ST.ToString("yyyyMMdd") + "单天超过最高收费标准" + OneDayMaxCost.ToString("f2") + ",按最高标准收费。:<-----";
                                    alist.Add(errmsg);
                                }
                                else
                                {
                                    errmsg = "------>:" + iDayIndex.ToString() + "、" + _ST.ToString("yyyyMMdd") + "一整天的费用为" + idayMoney.ToString() + " :<-----";
                                    alist.Add(errmsg);
                                }
                                iDayIndex++;

                            }
                            _CalcM += OneDayCash;


                            #endregion
                        }
                        #endregion
                    }

                    _ST = _ST.AddDays(1);
                }


            }
            catch (Exception ex)
            {
                rt.result = "FAIL";
                rt.errcode = "-6";
                rt.errmsg = "计费出错:" + ex.Message;
            }

            rt.paycash = _CalcM;
            alist.Add("{  " + ST.ToString("yyyy-MM-dd HH:mm:00") + "   " + OT.ToString("yyyy-MM-dd HH:mm:00") + "  共停车  " + StopTimeInfo + ",合计费用:" + _CalcM.ToString("f2") + "  }");
            rt.alist = alist;
            result = Newtonsoft.Json.JsonConvert.SerializeObject(rt);
            return result;
        }
        #endregion

        #region 计算一天内时段的费用
        /// <summary>
        /// 出错信息
        /// </summary>
        string ExceptionInfo = "";
        /// <summary>
        /// 计算一天内时段的费用
        /// </summary>
        /// <param name="_ST"></param>
        /// <param name="_OT"></param>
        /// <param name="_Cash"></param>
        /// <param name="alist"></param>
        /// <returns></returns>
        private decimal CalcOneDayCast(DateTime _ST, DateTime _OT, ref ArrayList alist, bool boFirstDay)
        {
            try
            {
                ExceptionInfo = "";

                #region 
                string errmsg = "";
                decimal OneDayValue = 0;

                _OT = DateTime.Parse(_ST.ToString("yyyy-MM-dd ") + _OT.ToString("HH:mm:00"));
                TimeSpan ts = _OT.Subtract(_ST);
                alist.Add("------>:" + iDayIndex.ToString() + "、" + _ST.ToString("yyyy-MM-dd HH:mm:00") + "    " + _OT.ToString("yyyy-MM-dd HH:mm:00"));
                bool boReturn = false;
                if (boFirstDay || iAfter24H == 0)
                {
                    //第一天或都重新计费
                    if (ts.TotalMinutes < FreeMinute)
                    {
                        alist.Add(ts.TotalMinutes.ToString() + "小于" + FreeMinute.ToString() + "不收费。");
                        boReturn = true;
                        //return OneDayValue;
                    }
                    else if (ts.TotalMinutes <= firstHour * 60)
                    {
                        OneDayValue += firstCash;
                        alist.Add("超过" + FreeMinute.ToString() + "分钟,在" + firstHour.ToString() + "小时内" + firstCash.ToString() + "元");
                        boReturn = true;
                        // return OneDayValue;
                    }
                    else
                    {
                        _ST = _ST.AddHours(firstHour);
                        OneDayValue += firstCash;
                        alist.Add("超过" + FreeMinute.ToString() + "分钟,在" + firstHour.ToString() + "小时内" + firstCash.ToString() + "元");
                    }
                }
                if (!boReturn)
                {
                    #region 停车时间在同一天内
                    decimal _H_Start = decimal.Parse(_ST.ToString("HHmm"));
                    decimal _H_End = decimal.Parse(_OT.ToString("HHmm"));
                    alist.Add(_ST.ToString("HH:mm") + "  VS  " + _OT.ToString("HH:mm"));
                    //TimeSpan ts = _OT.Subtract(_ST);
                    //消费在一天内
                    for (int i = 0; i < timelist.Count; i++)
                    {
                        #region
                        // _timelist.Add("00:00&08:00&4");
                        string[] spt = timelist[i].ToString().Split(new char[] { '&' });
                        DateTime _StartDT = DateTime.Parse(_ST.ToString("yyyy-MM-dd") + " " + spt[0]);
                        DateTime _EndDT = DateTime.Parse(_ST.ToString("yyyy-MM-dd") + " " + spt[1]);
                        decimal _C_Start = decimal.Parse(spt[0].Replace(":", "").Trim());
                        decimal _C_End = decimal.Parse(spt[1].Replace(":", "").Trim());

                        decimal _SpCash = decimal.Parse(spt[2]);
                        //_H_Start06:00;   _C_Start:8:00;  _H_End:10:00;  _C_End:12:00
                        if (_H_Start <= _C_Start && _H_End >= _C_Start && _H_End <= _C_End)
                        {
                            //消费起始时间小于时段起始时间,消费截止时间在时段内
                            ts = _OT.Subtract(_StartDT);
                            decimal Dvalue = _SpCash * decimal.Parse(ts.TotalHours.ToString());
                            OneDayValue += Dvalue;
                            errmsg = "   " + (i + 1).ToString() + "、" + _StartDT.ToString("HH:mm") + " " + _EndDT.ToString("HH:mm") + " { " + _StartDT.ToString("HH:mm") + " " + _OT.ToString("HH:mm") + " } 耗时" + ts.TotalHours.ToString("f2") + "小时,单价" + _SpCash.ToString("f2") + ",合计费用为" + Dvalue.ToString("f2") + ";  \n";
                            alist.Add(errmsg);
                        }
                        else if (_C_Start >= _H_Start && _C_Start <= _H_End)// (_H_Start >= _C_Start && _H_End<= _C_End)
                        {
                            //整个时段内在消费
                            ts = _EndDT.Subtract(_StartDT);
                            decimal Dvalue = _SpCash * decimal.Parse(ts.TotalHours.ToString());
                            OneDayValue += Dvalue;
                            errmsg = "   " + (i + 1).ToString() + "、" + _StartDT.ToString("HH:mm") + " " + _EndDT.ToString("HH:mm") + " { " + _StartDT.ToString("HH:mm") + " " + _EndDT.ToString("HH:mm") + " } 耗时" + ts.TotalHours.ToString("f2") + "小时,单价" + _SpCash.ToString("f2") + ",合计费用为" + Dvalue.ToString("f2") + ";  \n";
                            alist.Add(errmsg);
                        }
                        else if (_H_Start >= _C_Start && _H_End <= _C_End)
                        {
                            //消费在时段内
                            ts = _OT.Subtract(_ST);
                            decimal Dvalue = _SpCash * decimal.Parse(ts.TotalHours.ToString());
                            OneDayValue += Dvalue;
                            errmsg = "   " + (i + 1).ToString() + "、" + _StartDT.ToString("HH:mm") + " " + _EndDT.ToString("HH:mm") + " { " + _ST.ToString("HH:mm") + " " + _OT.ToString("HH:mm") + " } 耗时" + ts.TotalHours.ToString("f2") + "小时,单价" + _SpCash.ToString("f2") + ",合计费用为" + Dvalue.ToString("f2") + ";  \n";
                            alist.Add(errmsg);
                        }
                        else if (_H_Start >= _C_Start && _H_Start <= _C_End &&
                            _H_End >= _C_Start && _H_End >= _C_End)
                        {
                            //消费起始时间在时段内,消费截止时间大于结束时间
                            ts = _EndDT.Subtract(_ST);
                            decimal Dvalue = _SpCash * decimal.Parse(ts.TotalHours.ToString());
                            OneDayValue += Dvalue;
                            errmsg = "   " + (i + 1).ToString() + "、" + _StartDT.ToString("HH:mm") + " " + _EndDT.ToString("HH:mm") + " { " + _ST.ToString("HH:mm") + " " + _EndDT.ToString("HH:mm") + " } 耗时" + ts.TotalHours.ToString("f2") + "小时,单价" + _SpCash.ToString("f2") + ",合计费用为" + Dvalue.ToString("f2") + ";  \n";
                            alist.Add(errmsg);
                        }
                        #endregion
                    }
                    #endregion
                }
                if (OneDayValue > OneDayMaxCost)
                {
                    errmsg = _ST.ToString("yyyy-MM-dd") + "单天费用" + OneDayValue.ToString("f2") + "超过最高收费标准" + OneDayMaxCost.ToString("f2") + ",按最高标准收费。:<-----";
                    OneDayValue = OneDayMaxCost;
                    alist.Add(errmsg);
                }
                else
                {
                    alist.Add(_ST.ToString("yyyy-MM-dd") + "当天合计费用:" + OneDayValue.ToString("f2") + " :<-----");
                }

                iDayIndex++;

                return OneDayValue;
                #endregion
            }
            catch (Exception ex)
            {
                ExceptionInfo = ex.Message;
                return -100;
            }
        }
        #endregion

    }

    /// <summary>
    /// 返回信息
    /// </summary>
    public class backdata
    {
        #region 返回信息
        /// <summary>
        /// 返回结果:OK/FAIL
        /// </summary>
        public string result
        {
            get;
            set;
        }

        /// <summary>
        /// 错误码
        /// </summary>
        public string errcode
        {
            get;
            set;
        }
        /// <summary>
        /// 错误信息
        /// </summary>
        public string errmsg
        {
            get;
            set;
        }
        /// <summary>
        /// 合计费用
        /// </summary>
        public decimal paycash
        {
            get;
            set;
        }
        /// <summary>
        /// 消费时长
        /// </summary>
        public decimal iHour
        {
            get;
            set;
        }

        /// <summary>
        /// 时段消费明细
        /// </summary>
        public ArrayList alist
        {
            get;
            set;
        }
        #endregion
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值