Extension logic
How a shift configuration becomes shifts with exact start and end times.
A shift is defined by the weekday, hour and minute it starts (for example Mon 10:00), so no shift is longer than 7 days. This page describes how that configuration becomes shifts with exact start and end times.
Basic procedure
Given a starting timestamp:
- Loop through all defined shift configurations; discard any with a starting day that does not match the weekday.
- From the remaining shift configurations; discard any with a starting hour before the hour of the day.
- From the remaining shift configurations; discard any with a starting minute before the minute of the hour.
- Sort any remaining shift configurations by hour, then minute in ascending order and then select the first (earliest hour, minute). The Day, Hour and Minute from this selected configuration is the starting time of the next shift in the schedule.
- If no matching shift configurations remains, advance the timestamp to the end of the day (00:00 next day) and repeat the process.
Use
The basic procedure can be used directly with an arbitrary timestamp to find the starting time of the next shift in the schedule.
To find the starting time of the shift that will follow an existing shift in the schedule, the procedure must be executed with the starting timestamp set to 1 minute after the starting time of the shift to be followed - any end time for the existing shift should be ignored. See the example below for an illustration of why this is important.
All time and date calculations during the extension process must be performed with respect to the time zone of the schedule itself.
Matching of day wildcards
- A shift configured with the day set to the
Dailywildcard will match any timestamp. - A shift configured with the day set to the
Weekdayswildcard will match any timestamp, where the abbreviated name of the day of the week (e.g. %a strftime(3) component) in the time zone of the schedule is one of the Mon-Fri set. - A shift configured with the day set to the
Weekendswildcard will match any timestamp, where the abbreviated name of the day of the week (e.g. %a strftime(3) component) in the time zone of the schedule is one of Sat or Sun.
In the app, the Start day column of the shifts table and the shift descriptions show Weekdays as Every Weekday and Weekends as Sat, Sun.
Daily is shown as Daily.
Examples
For simplicity these examples do not display the time zone, which is not relevant but can be assumed to be UTC.
Basic
Assuming a shift configuration of Mon 10:00, Fri 17:00, when executed for the week starting April 1st 2024, the next 4 returned shifts
would be:
2024-04-01 10:002024-04-05 10:002024-04-08 10:002024-04-12 10:00
This provides a schedule with a ~5-day shift covering the working week, and a ~2-day shift covering the weekend.
Daily and weekends
Assuming a shift configuration of Daily 10:00, Weekends 22:00, when executed on April 4th 2024, the next 7 returned shifts
would be:
2024-04-04 10:002024-04-05 10:002024-04-06 10:002024-04-06 22:002024-04-07 10:002024-04-07 22:002024-04-08 10:00
This provides a schedule with 24-hour shifts during weekdays, but adds an additional “overnight” shift on weekends resulting in a split of each weekend day (Sat, Sun) into two 12-hour shifts.
Extension after configuration change
This example shows why extension starts 1 minute after the start of the last existing shift, not from the end of that shift.
- Original shift configuration:
Mon 10:00 - Existing shift:
Mon 1st Apr 2024 10:00 - Mon 8th Apr 2024 09:59 - New shift configuration:
Mon 09:00 - Expected next shift:
Mon 8th Apr 2024 09:00 - Mon 15th Apr 2024 08:59
Moving the expected start time back by 1 hour creates an ambiguous situation for the schedule, either the next shift needs to start 1 hour prior to the end of the existing last shift, or if the end of the last shift is strictly observed and extension begins from 10am on Monday the 8th, the next starting time is not until 9am the following Monday, creating a 7-day gap in the schedule!
On-Call Optimizer prefers continuous coverage, so it uses the rule above: extension starts one minute after the last existing shift starts. In this example the next shift starts at 9:00 on Mon 8 Apr and overlaps the existing shift by one hour.