Xamarin实现DateTime数组周末天数统计及LOS溢出问题求解
问题根因
你遇到的LOS(大对象堆)溢出是死循环直接导致的,根因有两点:
DateTime是值类型,date.AddDays(1)不会修改原date变量本身,你没有将计算后的值赋值回date,所以for循环的终止条件date <= b永远成立,程序会无限向List<DateTime>中插入元素,直到内存耗尽触发OOM。- 方法逻辑也存在计算错误:你修改后的
removeWeekends返回的是工作日数量,但你后续用「总天数 - 工作日数量」得到的实际是周末天数,和你想要的有效休假天数完全相反。
修复方案
1. 修正死循环问题
把for循环里的迭代语句改成date = date.AddDays(1),同时可以优化掉没必要的List<DateTime>对象创建,直接计数即可,减少内存开销:
// 方法名可以改成更贴合功能的GetWorkDayCount public int GetWorkDayCount(DateTime a, DateTime b) { if (a > b) return 0; int workDayCount = 0; for (DateTime date = a; date <= b; date = date.AddDays(1)) { if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday) { workDayCount++; } } return workDayCount; }
2. 修正日期选择事件的计算逻辑
直接用返回的工作日数量作为有效天数即可,不需要再做减法:
void OnDateSelected(object sender, DateChangedEventArgs e) { if(dateTo.Date < dateFrom.Date) { leaveDaysLabel.Text = "Days: Invalid Selection"; leaveHoursLabel.Text = string.Empty; } else { int workDays = GetWorkDayCount(dateFrom.Date, dateTo.Date); leaveDaysLabel.Text = $"Days: {workDays}"; leaveHoursLabel.Text = $"Hours: {(workDays * 7.4).ToString()}"; } }
3. 可选性能优化
如果要适配跨度很大的日期范围场景,可以用数学公式直接计算工作日数,不需要遍历全部日期:
public int GetWorkDayCount(DateTime start, DateTime end) { if (start > end) return 0; TimeSpan ts = end - start; int totalDays = ts.Days + 1; int fullWeeks = totalDays / 7; int workDays = fullWeeks * 5; int remainingDays = totalDays % 7; for (int i = 0; i < remainingDays; i++) { DayOfWeek dw = start.AddDays(i).DayOfWeek; if (dw != DayOfWeek.Saturday && dw != DayOfWeek.Sunday) workDays++; } return workDays; }
内容的提问来源于stack exchange,提问作者aTubOfAdam
相关产品推荐
相关产品推荐

