跨天工作时间段判定:识别当前时间所属天数
问题与解决方案
问题背景
数据库中定义了如下工作时间规则:
- 周一:08:00-17:00
- 周二:08:00-15:00、17:00-23:00
- 周三:08:00-03:00(跨次日)
- 周四:08:00-03:00(跨次日)
- 周五:09:00-11:00
现有IsWithinWorkingTimes方法仅能判定时间是否属于工作时段,但无法区分跨天时段的归属日期——比如周四01:00实际属于周三的跨天时段,周三15:00也属于该时段。需要在API层实现逻辑,判断当前时间对应跨天时段的第一天还是第二天,且前端不可修改。
现有代码定义
工作时间模型类
public class WorkTimeFrameModel { /// <summary> /// 获取或设置星期几枚举的原始数值 /// </summary> public int DayOfWeek { get; set; } /// <summary> /// 获取或设置时段开始时间(TimeSpan类型) /// </summary> public TimeSpan StartTime { get; set; } /// <summary> /// 获取或设置时段结束时间(TimeSpan类型) /// </summary> public TimeSpan EndTime { get; set; } /// <summary> /// 获取或设置DayOfWeek属性对应的枚举值 /// </summary> public DayOfWeek DayOfWeekEnum { get { return (DayOfWeek)DayOfWeek; } set { DayOfWeek = (int)value; } } }
现有判定方法
internal bool IsWithinWorkingTimes(DateTime dateTime) { var startDate = dateTime.Date; var endDate = dateTime.Date; // 可能变化的跨天时段时间 var start = new TimeSpan(08, 00, 00); var end = new TimeSpan(03, 00, 00); // var start = new TimeSpan(08, 00, 00); // var end = new TimeSpan(17, 00, 00); startDate = startDate.Date + start; endDate = endDate.Date + end; if (start > end) { return dateTime > startDate || dateTime < endDate; } return dateTime >= startDate && dateTime <= endDate; }
解决方案实现
核心逻辑:
- 先匹配当天的所有时段,非跨天时段直接判断时间是否在区间内;跨天时段则判断时间是否在当天起始时间到23:59:59之间,若是则归属当天。
- 若当天无匹配,检查前一天的跨天时段,判断时间是否在00:00到前一天跨天结束时间之间,若是则归属前一天的跨天时段。
完整代码:
// 预先加载所有工作时段配置(可从数据库读取) private List<WorkTimeFrameModel> _workTimeFrames = new List<WorkTimeFrameModel> { new WorkTimeFrameModel { DayOfWeekEnum = DayOfWeek.Monday, StartTime = new TimeSpan(8,0,0), EndTime = new TimeSpan(17,0,0) }, new WorkTimeFrameModel { DayOfWeekEnum = DayOfWeek.Tuesday, StartTime = new TimeSpan(8,0,0), EndTime = new TimeSpan(15,0,0) }, new WorkTimeFrameModel { DayOfWeekEnum = DayOfWeek.Tuesday, StartTime = new TimeSpan(17,0,0), EndTime = new TimeSpan(23,0,0) }, new WorkTimeFrameModel { DayOfWeekEnum = DayOfWeek.Wednesday, StartTime = new TimeSpan(8,0,0), EndTime = new TimeSpan(3,0,0) }, new WorkTimeFrameModel { DayOfWeekEnum = DayOfWeek.Thursday, StartTime = new TimeSpan(8,0,0), EndTime = new TimeSpan(3,0,0) }, new WorkTimeFrameModel { DayOfWeekEnum = DayOfWeek.Friday, StartTime = new TimeSpan(9,0,0), EndTime = new TimeSpan(11,0,0) } }; /// <summary> /// 获取当前时间所属的工作时段框架 /// </summary> /// <param name="dateTime">待判断的时间</param> /// <returns>所属的WorkTimeFrameModel,无匹配则返回null</returns> public WorkTimeFrameModel GetBelongingWorkTimeFrame(DateTime dateTime) { var currentDay = dateTime.DayOfWeek; var currentTime = dateTime.TimeOfDay; // 检查当天的所有时段 foreach (var frame in _workTimeFrames.Where(f => f.DayOfWeekEnum == currentDay)) { if (frame.StartTime <= frame.EndTime) { // 非跨天时段,直接判断时间区间 if (currentTime >= frame.StartTime && currentTime <= frame.EndTime) { return frame; } } else { // 跨天时段,判断是否属于当天的起始部分(当天StartTime到23:59:59) if (currentTime >= frame.StartTime) { return frame; } } } // 检查前一天的跨天时段(当前时间属于前一天的跨天结束部分) var previousDay = currentDay == DayOfWeek.Sunday ? DayOfWeek.Saturday : currentDay - 1; foreach (var frame in _workTimeFrames.Where(f => f.DayOfWeekEnum == previousDay && f.StartTime > f.EndTime)) { if (currentTime <= frame.EndTime) { return frame; } } // 无匹配工作时段 return null; }
使用说明
调用GetBelongingWorkTimeFrame方法后,返回的WorkTimeFrameModel中的DayOfWeekEnum即为当前时间所属的时段日期:
- 例1:输入周三15:00,返回周三的跨天框架,说明属于第一天;
- 例2:输入周四01:00,返回周三的跨天框架,说明属于该时段的第二天;
- 可直接在API层集成该方法,替代原有判定逻辑或扩展归属判断功能。
内容的提问来源于stack exchange,提问作者user1702369
相关产品推荐
相关产品推荐

