You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:45:00