计算一周内班次间的时间差(分钟)及代码异常排查
Hey there! Let's work through this shift interval calculation problem together. From what you've shared, we need to populate the interval list with the time gaps (in minutes) between consecutive shifts—including the wrap-around from the last shift back to the first one in the weekly cycle.
First, Let's Clarify the Requirements
- Each entry in
intervalrepresents the minutes between the end of one shift and the start of the next shift - Examples:
- If a shift ends at 'Mon' 22:00 and the next starts at 'Tue' 02:00 → 240 minutes
- If the last shift ends at 'Sun' 23:00 and the first shift starts at 'Mon' 01:00 → 120 minutes
Common Pitfalls in Your Current Code
Chances are your code is missing one or more of these critical logic pieces:
- Weekly cycle wrap-around: Forgetting that after Sunday comes Monday, so we need to account for a full week's minutes when calculating the gap from the last shift back to the first.
- Cross-day time handling: Shifts that end on the next day (e.g., a shift starting at 22:00 and ending at 02:00) require adjusting the end time to reflect the next day's minutes.
- Unsorted shifts: If your
shiftslist isn't ordered by the actual start time of the shifts in the week, your interval calculations will be completely off.
A Fix That Covers All Cases
Here's a robust implementation that addresses all these gaps. We'll convert everything to total minutes since the start of the week to make calculations straightforward:
# Map weekday names to numerical values (Mon = 0, Tue = 1, ..., Sun = 6) weekday_order = {'Mon': 0, 'Tue': 1, 'Wed': 2, 'Thu': 3, 'Fri': 4, 'Sat': 5, 'Sun': 6} MINUTES_PER_DAY = 1440 # 24 hours * 60 minutes def hhmm_to_minutes(time_str): """Convert a 'HH:MM' string to total minutes since midnight.""" hours, mins = map(int, time_str.split(':')) return hours * 60 + mins def get_week_minutes(day, time_str): """Convert a day + time to total minutes since the start of Monday.""" day_offset = weekday_order[day] * MINUTES_PER_DAY time_mins = hhmm_to_minutes(time_str) return day_offset + time_mins # Example shifts list (replace with your actual data) shifts = [ ['Mon', '22:00', '02:00'], # Ends Tue 02:00 ['Tue', '08:00', '16:00'], # Ends Tue 16:00 ['Sun', '23:00', '01:00'] # Ends Mon 01:00 ] # Step 1: Sort shifts by their start time in the week (critical!) sorted_shifts = sorted(shifts, key=lambda s: get_week_minutes(s[0], s[1])) interval = [] total_shifts = len(sorted_shifts) for i in range(total_shifts): # Get current shift's end time (handle cross-day shifts) current_day, _, current_end = sorted_shifts[i] current_end_mins = get_week_minutes(current_day, current_end) current_start_mins = get_week_minutes(current_day, sorted_shifts[i][1]) # If end time is earlier than start, it's a cross-day shift—add a full day's minutes if current_end_mins < current_start_mins: current_end_mins += MINUTES_PER_DAY # Get next shift's start time (wrap around to first shift if we're at the last one) next_shift = sorted_shifts[(i + 1) % total_shifts] next_start_mins = get_week_minutes(next_shift[0], next_shift[1]) # Calculate the interval, handle week wrap-around if needed gap = next_start_mins - current_end_mins if gap < 0: gap += 7 * MINUTES_PER_DAY # Add a full week's minutes to fix negative gaps interval.append(gap) print(interval)
Let's Verify This Works
Using the example shifts above:
- The first gap is from Tue 02:00 to Tue 08:00 → 360 minutes
- The second gap is from Tue 16:00 to Sun 23:00 → 7620 minutes (5 days + 7 hours)
- The third gap is from Mon 01:00 to Mon 22:00 → 1260 minutes (19 hours)
To match your exact 120-minute gap example, adjust the shifts so the last shift ends at Sun 23:00 and the first shift starts at Mon 01:00—the code will correctly calculate that 120-minute gap.
Key Takeaways
- Always sort your shifts by their weekly start time first—this ensures we're calculating gaps between consecutive shifts in the right order.
- Convert all times to total minutes since the start of the week to avoid messy day/time arithmetic.
- Don't forget to handle cross-day shifts and weekly wrap-around with minute adjustments.
内容的提问来源于stack exchange,提问作者JON PANTAU

