C# 计算每周和每月固定日期
最近发现写程序不是简单的实现功能,过程中偶尔伴随者一点小小的算法,比如排序算法,比如周期性的数据等等,发现算法不仅仅需要考虑全面,而且要计算简便、性能优良,而我远远没有达到要求!
一:周、月固定日期
/// <summary> /// 保洁计划按周获取日期 /// </summary> /// <param name="startDate">开始时间</param> /// <param name="endDate">结束时间</param> /// <param name="date">周开始日期</param> /// <returns></returns> public List<DateTime> GetListDatekForCleanPlan(DateTime startDate, DateTime endDate, int date, int cycle) { //算法:通过计算开始时间(startdate)与规定开始周期(date)的差 // 将开始时间增加至第一个周期的开始时间,然后循环得出每周的一个时间 //周:每周按照七天计算 //月:需要考虑最大天数不一致,原则采用设置天数和最大天数的比较值 //计算开始时间和规定时间之间的差值 List<DateTime> listdate = new List<DateTime>(); if (cycle == 0)//周 { int dayString = (int)startDate.DayOfWeek - date; //将开始时间增加到第一个周期的第一天 if (dayString >= 0) { startDate = startDate.AddDays(7 - dayString); } else { startDate = startDate.AddDays(-dayString); } while (startDate <= endDate) { if (startDate.Date >= DateTime.Now.Date) { break;//今日之前不添加保洁记录 } listdate.Add(startDate); startDate = startDate.AddDays(7); } } else//月 { int dayString = (int)startDate.Day - date; if (dayString >= 0)//本月不加保洁,直接开始下月 { startDate = Convert.ToDateTime(startDate.Year + "-" + startDate.AddMonths(1).Month + "-" + startDate.Day);//加一个月 } while (startDate <= endDate)//这里的算法有问题 { DateTime cleandate = new DateTime(); //判断当月最大天数是否大于指定日期,如果当月没有指定日期就按照最大一天安排打扫 if (date <= DateTime.DaysInMonth(startDate.Year, startDate.Month)) { cleandate = Convert.ToDateTime(startDate.Year + "-" + startDate.Month + "-" + date); } else { cleandate = Convert.ToDateTime(startDate.Year + "-" + startDate.Month + "-" + DateTime.DaysInMonth(startDate.Year, startDate.Month)); } if (cleandate.Date <= DateTime.Now.Date) { startDate = startDate.AddMonths(1); continue;//今日之前不添加保洁记录 } listdate.Add(cleandate); startDate = startDate.AddMonths(1); } } return listdate; }
这个写法待整理
二:上下排序算法
在一个小功能中用到,需要对列表展示数据可上移一位可下移一位,而且考虑可用与不可用属性
修改排序:
1 /// <summary> 2 /// 支付方式排序 3 /// </summary> 4 /// <param name="ID">当前id</param> 5 /// <param name="isUp">true->上移;false->下移</param> 6 /// <returns></returns> 7 public bool ChangePaymentTypeLevel(int ID, bool isUp) 8 { 9 //排序分为两部分,第一:有效记录中可以对记录上移一位和下移一位 10 //第二:无效记录重新排序,排在有效记录后 11 //通过两个规则完成,无效记录在后,有效记录在前,可以对有效记录调整顺序的操作 12 try 13 { 14 using (var trans = new TransactionScope()) 15 { 16 using (var dbContext = new ConfigDbContext()) 17 { 18 var commerid = ConfigManager.GetCurrentLoginInfoCommercialTenantID();//商户id 19 IEnumerable<PaymentType> paymentlist = dbContext.PaymentType.Where(p => p.CommercialTenantID == commerid).OrderBy(p => p.Level).ToList();//全部记录 20 var status = (byte)EnumPaymentTypeStatus.valid;//有效状态 21 var thispayment = paymentlist.Where(p => p.ID == ID).FirstOrDefault();//本条记录 22 if (paymentlist != null && thispayment != null && thispayment.Status == status) 23 { 24 var paymentstatuscount = paymentlist.Where(p => p.Status == status).Count();//总记录数 25 if ((thispayment.Level < paymentstatuscount && !isUp) || thispayment.Level != 1 && isUp)//上升和下降的时候都不是不可操作的那一个 26 { 27 //对本身和相邻记录进行调换等级(排序)start 28 var thislevel = thispayment.Level;//本等级 29 byte changelevel = 0;//需要改变的等级,上移时意味着上一条记录的等级,下移时意味着下一条记录的等级,这里通过等级去寻找记录 30 if (isUp)//上移 31 { 32 changelevel = Convert.ToByte(thispayment.Level - 1);//上一条记录等级 33 } 34 else//下移 35 { 36 changelevel = Convert.ToByte(thispayment.Level + 1);//下一条记录等级 37 } 38 var changepayment = paymentlist.Where(p => p.Level == changelevel).FirstOrDefault();//需要改变的记录 39 dbContext.PaymentType.Where(p => p.ID == changepayment.ID).Update(p => new PaymentType() { Level = thislevel });//改变相邻记录等级 40 dbContext.PaymentType.Where(p => p.ID == thispayment.ID).Update(p => new PaymentType() { Level = changelevel });//改变本条记录等级 41 //对本身和相邻记录进行调换等级(排序)end 42 43 44 //修改剩余支付类型排序,自增长 45 var otherpayment = paymentlist.Where(p => p.Status != status).ToList();//获取无效状态的记录 46 foreach (var item in otherpayment) 47 { 48 item.Level = (byte)(otherpayment.IndexOf(item) + 1 + paymentstatuscount);//修改排序等级自增长:本身位数加总的有效状态总数 49 dbContext.Update(item,false); 50 } 51 dbContext.SaveChanges(); 52 trans.Complete(); 53 return true; 54 } 55 else 56 { 57 //无聊的客户将最后一个有效的支付方式下移,告诉他成功了! 58 //第一个还要上移,告诉他成功了! 59 //页面最后对第一条和最后一条进行了限制不能修改排序(删除排序操作按钮,哈哈) 60 return true; 61 } 62 } 63 else 64 { 65 //有效且是第一个 66 return false; 67 } 68 } 69 } 70 } 71 catch (Exception es) 72 { 73 return false; 74 } 75 }
修改状态-调整排序
/// <summary> /// 更新支付类型状态 /// </summary> /// <param name="ID"></param> /// <returns></returns> public bool ChangePaymentTypeStatus(int ID) { //1:修改有效状态的排序 //2:修改本身记录的排序 //3:修改无效状态的排序 //4:本记录不在有效无效列表记录中计算 try { using (TransactionScope scope = new TransactionScope()) { using (var dbContext = new ConfigDbContext()) { var paymenttype = dbContext.PaymentType.Find(ID);//本条记录 if (paymenttype != null) { //实时的状态信息,不考虑并发,状态转换 var status = paymenttype.Status == (byte)EnumPaymentTypeStatus.valid ? (byte)EnumPaymentTypeStatus.invalid : (byte)EnumPaymentTypeStatus.valid; var commerid = ConfigManager.GetCurrentLoginInfoCommercialTenantID();//商户id var paymentlist = dbContext.PaymentType.Where(p => p.CommercialTenantID == commerid).ToList();//全部列表 //有效且非本身按照等级排序 var paymentstatuslist = paymentlist.Where(p => p.Status == (byte)EnumPaymentTypeStatus.valid & p.ID != ID).OrderBy(p => p.Level).ToList(); //有效状态,从1开始重新排序 foreach (var item in paymentstatuslist) { item.Level = (byte)(paymentstatuslist.IndexOf(item) + 1); dbContext.Update(item, false); } dbContext.SaveChanges(); //本身这条记录的排序,等于除了本身之外的有效状态总数加1 dbContext.PaymentType.Where(p => p.ID == ID).Update(p => new PaymentType() { Status = status, Level = (byte)(paymentstatuslist.Count() + 1) }); //无效状态除本条记录列表 var paymentinvalidlist = paymentlist.Where(p => p.Status == (byte)EnumPaymentTypeStatus.invalid & p.ID != ID).OrderBy(p => p.Level).ToList(); foreach (var item in paymentinvalidlist) { item.Level = (byte)(paymentinvalidlist.IndexOf(item) + 1 + paymentstatuslist.Count() + 1); dbContext.Update(item, false); } dbContext.SaveChanges(); scope.Complete(); return true; } else { return false; } } } } catch (Exception) { return false; } }