Time zones and Daylight Saving Time (DST)
The Employee Shift Scheduling model supports multiple time zones and DST by accepting all date time attributes in the ISO 8601 local date time with an offset to UTC format, for example:
-
2024-03-01T08:00:00
in London corresponds to theUTC
time zone offset and becomes2024-03-01T08:00:00Z
(Z
standing forUTC+0
offset), -
2024-03-01T08:00:00
in Atlanta corresponds to theUTC-4
time zone offset and becomes2024-03-01T08:00:00-04
.
Let’s start with DST change handling.
1. Daylight Saving Time (DST)
Since the model accepts all date times as a local date time with an offset to UTC, the client has full control over specifying how to cope with an extra hour, or a missing hour, during a DST change:
Imagine Carl has an overnight shift in Atlanta from 22:00 to 06:00 during the DST change to summer time. At 02:00 local time, the clock jumps 1 hour forward to 03:00. As a result, Carl’s shift will be 1 hour shorter if he finishes at his usual finish time of 06:00, alternatively, if Carl finishes at 07:00 instead of 06:00 his shift will still have a duration of 8 hours.
You can specify both scenarios by using the appropriate offset when defining the shift start and end. For instance:
-
After the DST change to winter time in Atlanta, the offset changes from
-4
to-5
. -
After the DST change to summer time in Atlanta, the offset changes from
-5
to-4
.
-
Keep duration
-
Keep end local time
Keep shift duration, finish at 07:00 local time:
{
"shifts": [
{
"id": "Carl's shift",
"start": "2024-03-09T22:00:00-5",
"end": "2024-03-10T07:00:00-4"
}
]
}
Keep shift end at 06:00 local time, shorten the shift by one hour:
{
"shifts": [
{
"id": "Carl's shift",
"start": "2024-03-09T22:00:00-5",
"end": "2024-03-10T06:00:00-4"
}
]
}
When DST changes for winter time, a similar situation occurs. This time at 03:00 the clock goes back 1 hour. The duration of Carl’s shift will be 1 hour longer if he finishes at his usual finish time of 06:00, alternatively, if Carl finishes at 05:00 the shift will still have a duration of 8 hours.
-
Keep duration
-
Keep end local time
Keep shift duration, finish at 05:00 local time:
{
"shifts": [
{
"id": "Carl's shift",
"start": "2024-11-02T22:00:00-4",
"end": "2024-11-03T05:00:00-5"
}
]
}
Keep shift end at 06:00 local time, prolong the shift by one hour:
{
"shifts": [
{
"id": "Carl's shift",
"start": "2024-11-02T22:00:00-4",
"end": "2024-11-03T06:00:00-5"
}
]
}
In the following sections, let’s look at how specific rule types behave when matching shifts within multiple time zones against a specified time period.
1.1. Employee Time Zones
To account for time zone changes during shifts or in the middle of a schedule the timeZoneId
can be defined on every employee.
{
"employees":
{
"id": "Carl",
"contracts": [
"Carl's Contract"
],
"timeZoneId": "Europe/Brussels"
}
}
The timeZoneId
expects a String
containing a time zone. Please use the full time zone name, e.g. "Europe/Brussels", "America/New_York", "Africa/Nairobi",…
For a list of time zones, see wikipedia.
2. Employee Period Rule and time zones
Let’s look at a specific example:
It takes 8 minutes to drive from Ranburne (Alabama) to Bowdon (Georgia), but these towns are in different time zones: Ranburn in Central Time (CT) and Bowdon in Eastern Time (ET).
Meet Beth, she is based in Ranburne, her home time zone offset is UTC-6
(Central Time
during winter time, we set her time zone ID to CST
):
-
Beth is assigned to
Shift A
in Ranburne from2024-02-04T23:00:00-6
to2024-02-05T06:00:00-6
. -
Next, she is assigned to
Shift B
in Bowdon, that isUTC-5
(Eastern Time
in winter), starting at midnight local time (2024-02-06T00:00:00-5
). That means2024-02-05T23:00:00-6
Beth’s time. -
Beth’s contract states that she is supposed to work at least 7 hours per day:
{
"contracts": [
{
"id": "Beth's Contract",
"periodRules": [
{
"id": "Min7HoursPerDay",
"period": "DAY",
"minutesWorkedMin": 420
}
]
}
],
"employees": [
{
"id": "Beth",
"contracts": [
"Beth's Contract"
],
"timeZoneId": "CST"
}
]
}
The default value for the timeZoneId attribute is "Z" for UTC+0 with no DST.
|
Had the Bowdon shift start time only been matched with Bowdon local date time, the rule would have prevented the above shift assignment to Beth because it would cause a contract violation.

3. Costs Rule and time zones
Let’s assume our schedule operates with shifts from two different sites, Atlanta (represented by the UTC-4
offset during winter time) and London (UTC+0
, also denoted as Z
):
-
On Monday
2024-02-05
midnight, London time, a new global feature will be rolled out, and the costs of both sites' shift assignments are expected to go higher than usual for the whole day. -
A global costs rule is set up to define increased costs for this time period:
{
"globalRules": {
"costsRules": [
{
"id": "IncreasedCostsDuringRollout",
"period": "rollout-day",
"totalCostsMax": 10000,
"zoneOffset": "Z"
}
]
}
}
The default value for the zoneOffset attribute is "Z" for UTC+0 .
|
-
Suppose
Shift A
starts at2024-02-04T20:00:00-4
. It will be matched correctly by the rule because the rule converts the time toUTC+0
resulting in2024-02-05T00:00:00Z
. -
Similarly,
Shift B
is starting at2024-02-05T20:00:00-4
. As expected, it willnot
be matched by the rule because the rule converts the time toUTC+0
resulting in2024-02-06T00:00:00Z
.
Had the shift start times been matched only as local date times, the rule would have matched shifts that are in fact outside the roll-out window.

4. Global Period Rule and time zones
A Global Period Rule is capable of two different types of matching behavior, with or without taking the zone offset into account.
4.1. Global Period Rule with a specified zone offset
The first mode of operation takes the zone offset into account and is activated by specifying the zone offset in the rule definition (see the example below).
An example use-case is similar to the Costs Rule described above.
Let’s assume that our schedule operates with shifts from two different sites, Atlanta (represented by the UTC-4
offset during winter time) and London (UTC+0
):
-
On Monday
2024-02-05
midnight, London time, a new global feature will be rolled out, and the costs of both sites' shift assignments are expected to go higher than usual for the whole day. -
A global period rule is set up to define the minimum and maximum number of shifts worked for this time period:
{
"globalRules": {
"minimumMaximumShiftsPerPeriod": [
{
"id": "IncreasedNumberOfShiftsDuringRollout",
"period": "rollout-day",
"shiftsWorkedMin": 20,
"shiftsWorkedMax": 30,
"zoneOffset": "Z"
}
]
}
}
The default value for the zoneOffset attribute in this rule is null , meaning the rule will assume the local date time mode of operation (see below)!
|
-
Suppose
Shift A
starts at2024-02-04T20:00:00-4
. It will be matched correctly by the rule because the rule converts the time toUTC+0
resulting in2024-02-05T00:00:00Z
. -
Similarly,
Shift B
starts at2024-02-05T20:00:00-4
. As expected, it willnot
be matched by the rule because the rule converts the time toUTC+0
resulting in2024-02-06T00:00:00Z
.

This mode of Global Period Rule operation is useful when multiple time zones need to synchronize on the same period on the timeline. You can imagine it as all relevant date times being converted into a time instant (the number of milliseconds from the start of the epoch) and then compared.
4.2. Global Period Rule with an unspecified zone offset
The second mode of operation matches the shifts based on the local date time only and is activated by not
specifying the zone offset in the rule definition:
Again, let’s assume that our schedule operates with shifts from two different sites, Atlanta (represented by the UTC-4
offset during winter time) and London (UTC+0
):
-
The company declares Monday
2024-02-05
as a day off for all its sites. Monday2024-02-05
starts and ends at a different point on the global timeline for each time zone. -
A global period rule with an unspecified zone offset is used to set the maximum number of shifts worked that day to zero:
{
"globalRules": {
"minimumMaximumShiftsPerPeriod": [
{
"id": "IncreasedNumberOfShiftsDuringRollout",
"period": "rollout-day",
"shiftsWorkedMin": 0,
"shiftsWorkedMax": 0,
"zoneOffset": null
}
]
}
}
The default value for the zoneOffset attribute is null , therefore the attribute can be omitted completely.
|
-
Suppose
Shift A
starts at2024-02-04T20:00:00-4
. This time, it will not be matched by the rule because the rule uses only the local date time part2024-02-04T20:00:00
during matching. -
Similarly,
Shift B
starts at2024-02-05T20:00:00-4
. As expected, it will be matched by the rule because the rule compares only the local date time part2024-02-05T20:00:00
.

This mode of Global Period Rule operation is useful when the rule needs to match shifts in time periods local to each shift time zone. You can imagine it as the zone offset information being removed from all relevant date times.