基于8小时工作制的C# .NET Core工时计算问题求助
问题排查与解决方案
核心错误原因
你误用了TimeSpan处理8小时工作制的工时计算——TimeSpan的days参数是按24小时自然日定义的,但你的业务逻辑是8小时=1个工作日,两者的“天”概念完全不同,这直接导致计算结果异常。
举你的例子:
- 总工时10个工作日(8小时/天)= 80小时,但你用
TimeSpan(10,0,0,0)表示的是10个自然日=240小时 - 已工作8个工作日5小时=69小时,你用
TimeSpan(8,5,0,0)表示的是8个自然日5小时=197小时 - 两者相减得到43小时(1天19小时自然日),和你预期的11小时(1个工作日3小时)完全不符
你的TotalWork函数逻辑本身没问题,它的作用是把零散的天、小时、分钟转换成规范的8小时制格式,但后续错误地用TimeSpan进行工时运算才是问题根源。
修正方案
放弃用TimeSpan处理8小时制工时,直接基于分钟/小时的数值计算,再通过TotalWork函数格式化结果。
基础版(小时级计算)
// 总工时:10个工作日 → 转换为总小时数 double totalWorkHours = 10 * 8; // 已工作:8个工作日5小时 → 转换为总小时数 double workedHours = 8 * 8 + 5; // 计算剩余总小时数 double remainingHours = totalWorkHours - workedHours; // 用TotalWork函数格式化剩余工时(传入0天、剩余总小时数、0分钟) double[] remainingWork = TotalWork(0, remainingHours, 0); // 结果:remainingWork[0] = 1, remainingWork[1] = 3, remainingWork[2] = 0 → 符合预期
进阶版(支持分钟级计算)
// 总工时:10天0小时0分钟 → 转换为总分钟数 double totalMins = 10 * 8 * 60; // 已工作:8天5小时0分钟 → 转换为总分钟数 double workedMins = 8 * 8 * 60 + 5 * 60; // 计算剩余总分钟数 double remainingMinsTotal = totalMins - workedMins; // 用TotalWork函数格式化剩余工时 double[] remainingWork = TotalWork(0, 0, remainingMinsTotal);
额外优化建议
- 数据类型优化:避免用
double存储天、小时、分钟,改用int更合适(工时都是整数单位)。 - 封装工具类:可以封装一个
WorkTime类统一处理8小时制的工时计算,提升代码可读性:
public class WorkTime { public int Days { get; set; } public int Hours { get; set; } public int Minutes { get; set; } public WorkTime(int days, int hours, int minutes) { var formatted = FormatWorkTime(days, hours, minutes); Days = formatted[0]; Hours = formatted[1]; Minutes = formatted[2]; } private int[] FormatWorkTime(int days, int hours, int minutes) { int totalHours = hours + minutes / 60; int remainingMins = minutes % 60; int totalDays = days + totalHours / 8; int remainingHours = totalHours % 8; return new[] { totalDays, remainingHours, remainingMins }; } public int ToTotalMinutes() { return Days * 8 * 60 + Hours * 60 + Minutes; } public static WorkTime Subtract(WorkTime total, WorkTime worked) { int remainingMins = total.ToTotalMinutes() - worked.ToTotalMinutes(); return new WorkTime(0, 0, remainingMins); } } // 使用示例 var totalWork = new WorkTime(10, 0, 0); var worked = new WorkTime(8, 5, 0); var remaining = WorkTime.Subtract(totalWork, worked); // remaining.Days = 1, remaining.Hours = 3, remaining.Minutes = 0
内容的提问来源于stack exchange,提问作者Hani
相关产品推荐
相关产品推荐

