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

C# Web应用计算工作日数(排除周末及公休日)的精度问题

嘿,我看到你刚学C#,在做计算工作日的Web应用时遇到了结果不准的问题——比如2018年5月23日到5月31日算出来是6天,但实际应该是7天对吧?咱们来把这个问题解决掉!

核心问题定位

先看你代码里的DaysLeft方法,循环条件是:

for (DateTime index = startDate; index < endDate; index = index.AddDays(1))

这里用了<,意味着结束日期当天不会被计入计算。比如你测试的5.23到5.31,循环只会跑到5.30,自然少了1天,这就是结果差1的直接原因。

另外还有几个可以优化的点:比如日期解析不够安全、排除日期的判断可以更简洁,还有没处理用户输入结束日期早于开始日期的情况。

修正后的完整代码

namespace testtest {
    public partial class First : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
        }

        protected void Button1_Click(object sender, EventArgs e) {
            // 先验证日期输入是否合法
            if (!DateTime.TryParseExact(TextBox1.Text, "dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture, 
                System.Globalization.DateTimeStyles.None, out DateTime startDate))
            {
                result.Text = "请输入正确格式的开始日期(dd/MM/yyyy)";
                return;
            }

            if (!DateTime.TryParseExact(TextBox2.Text, "dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture, 
                System.Globalization.DateTimeStyles.None, out DateTime endDate))
            {
                result.Text = "请输入正确格式的结束日期(dd/MM/yyyy)";
                return;
            }

            // 处理结束日期早于开始日期的情况
            if (endDate < startDate)
            {
                result.Text = "结束日期不能早于开始日期";
                return;
            }

            List<DateTime> publicHolidays = new List<DateTime> {
                DateTime.ParseExact("04/05/2018", "dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture)
            };

            int workDays = CalculateWorkDays(startDate, endDate, true, publicHolidays);
            result.Text = workDays.ToString();
        }

        public int CalculateWorkDays(DateTime startDate, DateTime endDate, bool excludeWeekends, List<DateTime> excludeDates) {
            int count = 0;
            // 把循环条件改成<=,包含结束日期当天
            for (DateTime currentDate = startDate; currentDate <= endDate; currentDate = currentDate.AddDays(1)) {
                bool isWeekend = excludeWeekends && (currentDate.DayOfWeek == DayOfWeek.Saturday || currentDate.DayOfWeek == DayOfWeek.Sunday);
                bool isExcludedHoliday = excludeDates.Any(holiday => holiday.Date == currentDate.Date);

                if (!isWeekend && !isExcludedHoliday) {
                    count++;
                }
            }
            return count;
        }
    }
}

关键修改说明

  • 修复循环条件:把index < endDate改成currentDate <= endDate,这样结束日期当天会被纳入计算,解决了你测试案例少1天的问题。
  • 更安全的日期解析:用DateTime.TryParseExact替代原来的ParseDate方法,既能确保日期格式正确,还能在用户输入错误时给出友好提示,避免程序崩溃。
  • 简化排除日期判断:用LINQ的Any方法替代手动循环判断,代码更简洁易读。
  • 增加输入合法性校验:处理了结束日期早于开始日期的情况,避免出现不合理的计算结果。

现在你再测试5月23日到5月31日的案例,应该就能得到正确的7天结果啦!

内容的提问来源于stack exchange,提问作者epiphany

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:22:50