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
相关产品推荐
相关产品推荐

