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

C#控制台任务工期计算错误修复与goto语句替换实现

问题修复及代码优化方案

一、计算逻辑错误原因

原代码的结束日期计算存在两个核心问题:

  • 仅对最终计算出的日期做周末判断,没有跳过计算周期内的所有周六周日,当日历跨度超过1周后,自然日和工作日的差值会越来越大,导致结果错误
  • 日期累加时多加了1天:开始日期当天已经算作第1个工作日,比如所需工作日为1时,结束日期就是开始日期,无需额外加1

二、代码结构优化思路

将不同功能的逻辑拆分为独立方法,用while循环替代所有goto语句,每个方法仅负责单一功能,后续新增参数或规则时只需要修改对应方法即可:

  • 通用整数输入校验方法:负责所有整数类型的输入校验,可自定义校验规则
  • 开始日期输入校验方法:专门负责日期格式校验和周末判断
  • 工作日结束日期计算方法:独立实现跨周末的工作日计算逻辑
  • 主方法:仅负责流程调度和重启判断

三、修复后的完整代码

public static class Program
{
    static void Main(string[] args)
    {
        while (true)
        {
            // 获取合法的任务总工时
            int totalTaskHours = GetValidIntInput(
                "Enter Total Time for the Task in Hours : ",
                "You have entered invalid value for total hours of task. Please enter a positive integer",
                input => input > 0);

            // 获取合法的每日工作时长
            int dailyWorkHours = GetValidIntInput(
                "\nEnter No of working hours per day: ",
                "Please enter an integer between 1 and 9 for working hours per day",
                input => input is > 0 and <= 9);

            // 获取合法的开始日期
            DateTime startDate = GetValidStartDate(
                "\nEnter the start date of the task (e.g.mm/dd/yyyy) : ",
                "You have entered an incorrect value for start date. Please enter a correct value",
                "Cannot start work on {0} because it is a {1}");

            // 计算所需工作日
            int requiredWorkDays = (int)Math.Ceiling((double)totalTaskHours / dailyWorkHours);
            Console.WriteLine($"\nTask will take {requiredWorkDays} working days");

            // 计算结束日期
            DateTime endDate = CalculateWorkEndDate(startDate, requiredWorkDays);
            Console.WriteLine($"The ending date will be {endDate:MM/dd/yyyy}");

            // 程序重启判断
            Console.WriteLine("\n\nProgram complete ... press Y to restart or any other key to exit.\n");
            if (Console.ReadKey(true).Key != ConsoleKey.Y)
            {
                break;
            }
            Console.Clear();
        }
    }

    /// <summary>
    /// 获取符合规则的整数输入
    /// </summary>
    /// <param name="prompt">输入提示语</param>
    /// <param name="errorMsg">校验失败提示语</param>
    /// <param name="validateRule">自定义校验规则</param>
    /// <returns>合法的整数输入</returns>
    private static int GetValidIntInput(string prompt, string errorMsg, Func<int, bool> validateRule)
    {
        int inputValue;
        while (true)
        {
            Console.WriteLine(prompt);
            if (int.TryParse(Console.ReadLine(), out inputValue) && validateRule(inputValue))
            {
                Console.WriteLine($"Input value is : {inputValue}");
                return inputValue;
            }
            Console.WriteLine(errorMsg);
        }
    }

    /// <summary>
    /// 获取符合规则的任务开始日期
    /// </summary>
    /// <param name="prompt">输入提示语</param>
    /// <param name="formatErrorMsg">格式错误提示语</param>
    /// <param name="weekendErrorMsg">周末日期提示语</param>
    /// <returns>合法的开始日期</returns>
    private static DateTime GetValidStartDate(string prompt, string formatErrorMsg, string weekendErrorMsg)
    {
        DateTime inputDate;
        while (true)
        {
            Console.WriteLine(prompt);
            if (!DateTime.TryParse(Console.ReadLine(), out inputDate))
            {
                Console.WriteLine(formatErrorMsg);
                continue;
            }
            if (inputDate.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday)
            {
                Console.WriteLine(string.Format(weekendErrorMsg, inputDate.ToString("MM/dd/yyyy"), inputDate.DayOfWeek));
                continue;
            }
            Console.WriteLine($"Start Date is : {inputDate:MM/dd/yyyy}");
            return inputDate;
        }
    }

    /// <summary>
    /// 计算任务结束日期,自动跳过周六周日
    /// </summary>
    /// <param name="startDate">任务开始日期(必须为工作日)</param>
    /// <param name="requiredWorkDays">所需工作日总数</param>
    /// <returns>任务结束日期(工作日)</returns>
    private static DateTime CalculateWorkEndDate(DateTime startDate, int requiredWorkDays)
    {
        DateTime currentDate = startDate;
        int completedDays = 1; // 开始日期当天算第一个工作日
        while (completedDays < requiredWorkDays)
        {
            currentDate = currentDate.AddDays(1);
            // 跳过周末
            if (currentDate.DayOfWeek is not DayOfWeek.Saturday and not DayOfWeek.Sunday)
            {
                completedDays++;
            }
        }
        return currentDate;
    }
}

四、测试验证

针对你提到的测试用例:总工时130、每日工作时长4、开始日期08/02/2021,计算得所需工作日为33天,运行上述代码得到的结束日期为09/15/2021,结果正确。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 13:24:01