Multiple Calendars
Work pertaining to a given activity is assumed to be done according to
a particular calendar.
A calendar is defined here in terms of a
work pattern for each day and a work week structure for each week.
In addition, each calendar may have holidays during
a given year.
You can associate calendars with Activities (using the
CALID variable in
the Activity data set) or Resources (using
observations with the keyword CALENDAR for the
OBSTYPE= variable in the Resource data set).
PROC CPM enables you to define very general calendars
using the WORKDATA, CALEDATA, and HOLIDATA data sets and
options in the PROC CPM statement. Recall that these data sets are
referred to as the Workday, Calendar, and Holiday data sets,
respectively. The Workday data set specifies distinct shift patterns
during a day. The Calendar data set specifies a typical
work week for any given calendar; for each day of a typical week, it
specifies the shift pattern that is followed. The
Holiday data set specifies a list of holidays and
the calendars that they refer to; holidays are defined either by
specifying the start of the holiday and its duration in
interval units,
or by specifying the start and end of the holiday period.
The Activity data set (the DATA= input data set) then
specifies the calendar that is used by each activity in the project
through the CALID variable (or a default variable _CAL_). Each of the
three data sets used to define calendars is described in greater detail
later in this section.
Each new value for the CALID variable in either the Calendar
data set or the Holiday data set defines a new calendar. If a calendar
value appears in the Calendar data set and not in the Holiday data set,
it is assumed to have the same holidays as the default calendar (the
default calendar is defined later in this section). If a
calendar value appears in the Holiday data set and not in the Calendar
data set, it is assumed to have the same work pattern structures
(for each week and within each day) as the default calendar. In the
Activity data set, valid values for the CALID variable are those that
are defined in either the Calendar data set
or the Holiday data set.
Cautions
The Holiday, Calendar, and Workday data sets and the processing of
holidays and different calendars are supported only when interval
is DAY, WEEKDAY, DTDAY, WORKDAY, DTWRKDAY, DTHOUR, DTMINUTE,
or DTSECOND. PROC CPM uses default specifications
whenever some information required to define a calendar is
missing or invalid.
The defaults have been chosen
to allow for consistency among different types of specifications and to
correct for errors in input, while maintaining compatibility with
earlier versions of PROC CPM. You get a wide range of control over the
calendar specifications, from letting PROC CPM define a single
calendar entirely from defaults, to defining several calendars of your
choice with precisely defined work patterns for each day of the
week and for each week. If the Calendar, Workday and Holiday data sets
are used along with multiple calendar specifications, it is important
to remember how all of the data sets and the various options interact
to form the work patterns for the different calendars.
The default calendar is a special calendar that is defined by PROC CPM;
its definition and uses are explained in this subsection.
If there is no CALID variable and no Calendar and Workday data
sets, the default calendar is defined by interval
and the DAYSTART= and DAYLENGTH= options in the PROC CPM statement. If
interval is DAY, DTDAY, DTHOUR, DTMINUTE or DTSECOND,
work is done on
all seven days of the week; otherwise,
Saturday and Sunday are considered to be
nonworking days. Further, if the schedule is computed as SAS datetime
values, the length of the working day is determined by
daystart and daylength.
All of the holidays specified in the Holiday data set refer to this
default calendar, and all of the activities in the project follow it.
Thus, if there is no CALID variable, the default calendar is the
only calendar that is used for all of the activities in the project.
If there is a CALID variable that identifies distinct calendars, you
can use an observation in the Calendar data set to define the work
week structure for the
default calendar. Use the value `0' (if CALID is a numeric variable) or
the value `DEFAULT' (if CALID is a character variable) to identify the
default calendar. In the absence of such an observation, the default
calendar is defined by interval, daystart,
and daylength, as described earlier. The default calendar
is used to substitute default work patterns for missing values in the
Calendar data set or to set default work week structures for newly
defined calendars in the Holiday data set.
All numeric variables in the Workday data set are assumed to denote
unique shift patterns during one working day. For each variable
the observations specify, alternately, the times when consecutive
shifts start and end. Suppose S1, S2, and S3
are numeric variables
formatted as TIME6. Consider the following Workday data:
S1 S2 S3
7:00 . 7:00 (start)
11:00 08:00 11:00 (end)
12:00 . . (start)
16:00 . . (end)
The variables S1, S2, and S3 define
three different work patterns. A missing
value in the first observation is assumed to be 0
(or 12:00 midnight); a missing value in any other observation is
assumed to denote 24:00 and ends the definition of the
shift. Thus, the workdays defined are:
-
S1 defines a workday starting at 7:00 a.m. and continuing until
4:00 p.m. with an hour off for lunch from
11:00 a.m. until 12:00 noon.
-
S2 defines a workday from
midnight to 8:00 a.m.
-
S3 defines a workday from 7:00 a.m. to 11:00 a.m.
The last two values for the variables S2 and S3
(both values are `24:00', by default) are ignored.
This data set can be used to define all of the unique shift patterns
that occur in any of the calendars in the project. These shift patterns
are tied to the different calendars in which they occur using the
Calendar data set.
The Calendar data set defines specific calendars using the names of
the shift variables in the Workday data set. Use the variable
specified in the
CALID statement or a variable named _CAL_
to identify the calendar name or number.
Character variables named _SUN_, _MON_, _TUE_,
_WED_, _THU_, _FRI_, and _SAT_
are used to indicate the work pattern that
is followed on each day of the week. Valid values for these variables
are `HOLIDAY', `WORKDAY' or,
any shift variable name defined in the Workday data set.
Note: A missing value for any of these variables is
assumed to denote that the work pattern for the corresponding day is
the same as for the default calendar.
When interval is specified as DTDAY, WORKDAY, or
DTWRKDAY, it is necessary to know the length of a
standard working
day in order to be able to compute the schedules consistently. For
example, a given calendar may have an eight-hour day on Monday,
Tuesday, and Wednesday and a
seven-hour day on Thursday and Friday. If a
given activity following that calendar has a duration of four days,
does it mean that its duration is equal to 8×4 = 32 hours or
7×4 = 28 hours? To avoid ambiguity, a numeric variable named
D_LENGTH can be specified in the Calendar data set to define the length
of a standard working day for the specified calendar. If this
variable is not found in the Calendar data set, all calendars for
the project are assumed to have a standard daylength as defined by the
default calendar.
For example, consider the following Calendar data:
_CAL_ _SUN_ _MON_ _TUE_ _FRI_ _SAT_ D_LENGTH
1 HOLIDAY S1 S1 S2 S3 8:00
2 HOLIDAY . . . HOLIDAY .
3 . . . . . .
These three observations
define three calendars: `1', `2', and `3'.
The values `S1', `S2', and `S3'
refer to the shift variables defined in the "WORKDATA Data Set" section.
Activities in the project can
follow either of these three calendars or the default calendar.
Suppose daystart has been specified as
9:00 a.m. and daylength is eight
hours. Further, suppose that interval is DTDAY. Using
these parameter specifications, PROC CPM defines the default calendar
and calendars 1, 2 and 3 using the Calendar data set just defined:
-
The default calendar (not specified explicitly in the Calendar data set)
is defined using interval, daystart, and
daylength.
It follows a seven-day week with each day being
an eight-hour day (from 9:00 a.m. to 5:00 p.m.).
Recall that the default calendar is defined to have seven or five
working days depending on whether interval is
DTDAY or WORKDAY, respectively.
-
Calendar `1' (defined in observation 1) has a holiday on Sunday; on
Monday and Tuesday work is done from 7:00 a.m. to 11:00 a.m. and
then from 12:00 noon to 4:00 p.m.; work on Friday is done
from 12:00 (midnight) to
8:00 a.m.; work on Saturday is done from 7:00 a.m. to
11:00 a.m.; on other
days work is done from
9:00 a.m. to 5:00 p.m., as defined by the default calendar.
The value of D_LENGTH specifies the number of hours in a standard work
day; when durations of activities are specified in terms of number of
workdays, then the value of D_LENGTH is used as a multiplier to convert
workdays to the appropriate number of hours.
-
Calendar `2' (defined in observation 2) has holidays on
Saturday and Sunday,
and on the remaining days, it follows the
standard working day as defined by
the default calendar.
-
Calendar `3' (defined in observation 3) follows the same definition as
the default calendar.
Note: If there are
multiple observations in the Calendar data set identifying the same
calendar, all except the first occurrence are ignored. The value `0'
(if CALID is a numeric variable) or the value `DEFAULT' (if CALID is a
character variable) refers to the default calendar. A missing value
for the CALID variable is also assumed to refer to the default calendar.
Note that the Calendar data set can be used to define
the default calendar also.
The HOLIDATA data set (referred to as the Holiday data set) defines
holidays for the different calendars
that may be
used in the project. Holidays are specified by using the HOLIDAY
statement. See the HOLIDAY statement earlier
in this chapter for a
description of the syntax. This data set must contain a variable
(the HOLIDAY variable) whose values specify the start of each holiday.
Optionally, the data set may also contain a variable (the HOLIDUR
variable) used to specify the length of each holiday or another
variable (the HOLIFIN variable) specifying the finish time
of each holiday. The variable specified by the CALID statement (or a
variable named _CAL_) can be used in this data set to identify the
calendar to which each holiday refers.
A missing value for the HOLIDAY variable in an observation causes that
observation to be ignored. If both the HOLIDUR and the HOLIFIN
variables have missing values in a given observation, the holiday
is assumed to start at the date and time specified for the HOLIDAY variable
and last one unit of interval where the INTERVAL= option has
been specified as interval.
If a given observation has valid
values for both the HOLIDUR and the HOLIFIN variables, only the
HOLIFIN variable is used so that the holiday is assumed to start and
end as specified by the HOLIDAY and HOLIFIN variables, respectively. A
missing value for the CALID variable causes the holiday to be included
in all of the calendars, including the default.
The HOLIDUR variable is a natural way of expressing vacation times
as n workdays, and
the HOLIFIN variable is more useful for defining
standard holiday periods, such as the CHRISTMAS holiday from 23DEC87 to
25DEC87 (both days inclusive). Note that the HOLIDUR variable is
assumed to be in units of interval and the procedure uses
the particular work pattern structure for the given calendar to compute the
length (finish time) of the holiday.
For example, consider the following Holiday data:
HOLISTA HOLIDUR HOLIFIN _CAL_
23DEC87 . 25DEC87 .
01JAN88 1 . 1
18JAN88 . . 2
28JAN88 3 . 2
28JAN88 3 . 3
Suppose calendars `1', `2', and `3'
and the default calendar have been
defined as described earlier in the description of the Calendar and
Workday data sets. Recall that in this example INTERVAL=DTDAY,
DAYSTART='09:00'T, and DAYLENGTH='08:00'T. Because the schedule is
computed as SAS datetime values (since INTERVAL=DTDAY), the holiday
values (specified here as SAS date values) are
converted to SAS datetime values.
The first observation in the Holiday data set has a missing value
for _CAL_ and, hence, the holiday in this observation pertains to
all the calendars. As defined by the Holiday data, the holiday lists for
the different calendars (not including breaks due to shift
definitions) are as shown in Table 2.23.
Note that, even though both calendars `2' and `3'
have the same
specifications for HOLISTA and HOLIDUR, the actual holiday
periods are
different for the two calendars. For calendar `2', the three days
starting from
Thursday, January 28, imply that the holidays are on Thursday,
Friday, and Monday
(because Saturday and Sunday are already holidays). For
calendar `3' (all seven
days are working days), the holidays are on Thursday,
Friday, and Saturday.
Table 2.23: Holiday Definitions
Calendar | Holiday Start | Holiday End |
0 | 23DEC87:09:00 | 25DEC87:16:59:59 |
1 | 23DEC87:09:00 | 25DEC87:07:59:59 |
| 01JAN88:00:00 | 01JAN88:07:59:59 |
2 | 23DEC87:09:00 | 25DEC87:16:59:59 |
| 18JAN88:09:00 | 18JAN88:16:59:59 |
| 28JAN88:09:00 | 01FEB88:16:59:59 |
3 | 23DEC87:09:00 | 25DEC87:16:59:59 |
| 28JAN88:09:00 | 30JAN88:16:59:59 |
You can use the GANTT procedure to visualize the breaks and holidays for
the different calendar. Figure 2.4
shows all the breaks and holidays
for the period between Christmas and New Year. Holidays and
breaks are denoted by *. Likewise, Figure 2.5 shows the vacation
periods in January for calendars `2' and `3'.
Christmas and New Year Holidays |
DEC DEC DEC DEC DEC DEC
22 22 23 23 24 24
_cal_ 00:00 12:00 00:00 12:00 00:00 12:00
-+-----------+-----------+-----------+-----------+-----------+-
0 |*********--------********************************************|
1 |*******----*----*********************************************|
2 |*********--------********************************************|
3 |*********--------********************************************|
-+-----------+-----------+-----------+-----------+-----------+-
|
DEC DEC DEC DEC DEC DEC DEC
24 25 25 26 26 27 27
12:00 00:00 12:00 00:00 12:00 00:00 12:00
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|*********************************************--------****************----|
|*******************************************----**************************|
|*************************************************************************|
|*********************************************--------****************----|
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|
DEC DEC DEC DEC DEC DEC DEC
27 28 28 29 29 30 30
12:00 00:00 12:00 00:00 12:00 00:00 12:00
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|-----****************--------****************--------****************----|
|*******************----*----***************----*----*****************----|
|*********************--------****************--------****************----|
|-----****************--------****************--------****************----|
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|
DEC DEC DEC JAN JAN JAN JAN
30 31 31 01 01 02 02
12:00 00:00 12:00 00:00 12:00 00:00 12:00
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|-----****************--------****************--------****************----|
|-----****************--------**************************************----**|
|-----****************--------****************--------********************|
|-----****************--------****************--------****************----|
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|
|
Figure 2.4: Christmas and New Year Holidays for Multiple Calendars
Vacation Times for Calendars 2 and 3 |
JAN JAN JAN JAN JAN JAN JAN
18 18 19 19 20 20 21
_cal_ 00:00 12:00 00:00 12:00 00:00 12:00 00:00
-+-----------+-----------+-----------+-----------+-----------+-----------+-
2 |*********************************--------****************--------********|
3 |*********--------****************--------****************--------********|
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|
JAN JAN JAN JAN JAN JAN JAN
21 21 22 22 23 23 24
00:00 12:00 00:00 12:00 00:00 12:00 00:00
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|*********--------****************--------********************************|
|*********--------****************--------****************--------********|
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|
JAN JAN JAN JAN JAN JAN JAN
24 24 25 25 26 26 27
00:00 12:00 00:00 12:00 00:00 12:00 00:00
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|*********************************--------****************--------********|
|*********--------****************--------****************--------********|
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|
JAN JAN JAN JAN JAN JAN JAN
27 27 28 28 29 29 30
00:00 12:00 00:00 12:00 00:00 12:00 00:00
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|*********--------********************************************************|
|*********--------********************************************************|
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|
JAN JAN JAN JAN FEB FEB FEB
30 30 31 31 01 01 02
00:00 12:00 00:00 12:00 00:00 12:00 00:00
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|*************************************************************************|
|*********************************--------****************--------********|
-+-----------+-----------+-----------+-----------+-----------+-----------+-
|
|
Figure 2.5: Vacation Time for Calendars 2 and 3
Copyright © 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.