Example 2.10: Multiple Calendars
This example illustrates the use of multiple calendars within a project.
Different scenarios are presented to show the use of different calendars
and how project schedules are affected.
Output 2.10.1 shows the data set WORKDATA, which defines
several shift patterns. These shift patterns are appropriately
associated with three different calendars in the data set
CALEDATA,
also shown in the same output. The three calendars are defined
as follows:
- The DEFAULT
calendar has five eight-hour days (Monday through Friday) and holidays on
Saturday and Sunday.
- The calendar OVT_CAL specifies an overtime calendar
that has 10-hour work days on Monday through Friday and a half day
on Saturday and a holiday on Sunday.
- The calendar PROD_CAL follows a
more complicated work pattern: Sunday is a holiday;
on Monday work is done from 8 a.m. through
midnight with a two hour break from 6 p.m. to 8 p.m.; on Tuesday through
Friday work is done round the clock with two 2-hour breaks from
6 a.m. to 8 a.m. and 6 p.m. to 8 p.m.; on Saturday the work shifts
are from midnight to 6 a.m. and again from 8 a.m. to 6 p.m.
In other words, work is done continuously
from 8 a.m. on Monday morning to 6 p.m. on Saturday with two hour breaks
every day at 6 a.m. and 6 p.m.
Output 2.10.1: Workday and Calendar Data Sets
Multiple Calendars |
Workdays Data Set |
Obs |
fullday |
halfday |
ovtday |
s1 |
s2 |
s3 |
1 |
8:00 |
8:00 |
8:00 |
. |
8:00 |
. |
2 |
16:00 |
12:00 |
18:00 |
6:00 |
18:00 |
6:00 |
3 |
. |
. |
. |
8:00 |
20:00 |
8:00 |
4 |
. |
. |
. |
18:00 |
. |
18:00 |
5 |
. |
. |
. |
20:00 |
. |
. |
6 |
. |
. |
. |
. |
. |
. |
Multiple Calendars |
CALENDAR Data Set |
Obs |
cal |
_sun_ |
_mon_ |
_tue_ |
_wed_ |
_thu_ |
_fri_ |
_sat_ |
1 |
DEFAULT |
holiday |
fullday |
fullday |
fullday |
fullday |
fullday |
holiday |
2 |
OVT_CAL |
holiday |
ovtday |
ovtday |
ovtday |
ovtday |
ovtday |
halfday |
3 |
PROD_CAL |
holiday |
s2 |
s1 |
s1 |
s1 |
s1 |
s3 |
|
The same set of holidays is
used as in Example 2.9, except that in this case the holiday for
New Year's is
defined by specifying both the start and finish time for the holiday
instead of defaulting to a one-day long holiday. When
multiple calendars are involved, it is often less confusing to
define holidays by specifying both a start and a finish time
for the holiday instead of the start time and duration. Output 2.10.2
displays the Holiday data set.
Output 2.10.2: Holiday Data Set
Multiple Calendars |
Holidays Data Set |
Obs |
holiday |
holifin |
holidur |
1 |
25DEC91 |
27DEC91 |
4 |
2 |
01JAN92 |
01JAN92 |
. |
|
Note that the data set HOLIDAYS does not include any variable
identifying the
calendars with which to associate the holidays. By default, the procedure
associates the two holiday periods with all the calendars.
An easy way to visualize all
the breaks and holidays for each calendar is to use a Gantt chart,
plotting a bar for each calendar from the start of the project to
January 2, 1992, with all the holiday and work shift specifications.
The following program produces Output 2.10.3.
Note that holidays and breaks
are marked with a solid fill pattern.
goptions hpos=160 vpos=25 ftext=swiss;
title h=1.5 'Multiple Calendars';
title2 'Breaks and Holidays for the Different Calendars';
proc gantt data=cals graphics
calendar=calendar holidata=holidays
workday=workdata;
chart / interval=dtday mininterval=dthour skip=2
holiday=(holiday) holifin=(holifin)
markbreak daylength='08:00't calid=cal
ref='2dec91:00:00'dt to '2jan92:00:00'dt by dtday
nolegend nojobnum increment=16
hpages=6;
id cal;
run;
Output 2.10.3: Gantt Chart Showing Breaks and Holidays for Multiple Calendars
The Activity data set used in Example 2.9 is modified by adding a
variable called cal, which sets the calendar to be `PROD_CAL'
for the activity `Production', and `OVT_CAL' for the activity
`Prototype', and
the DEFAULT calendar for the other activities. Thus, in both the
Activity data set and the Calendar data set,
the calendar information is conveyed through
a CALID variable, cal.
PROC CPM is first invoked without reference to the
CALID variable. Thus, the procedure recognizes only the first observation
in the Calendar data set (a warning is issued to the log to this effect),
and only the default calendar is used for all activities in the project.
The daylength parameter is interpreted as the length of a standard
work day; all the durations are assumed to be in units of this standard
work day.
Output 2.10.4 displays the schedule obtained. Note that the project
is scheduled to finish on March 13, 1992, at 12 noon.
data widgcal;
set widget9;
if task = 'Production' then cal = 'PROD_CAL';
else if task = 'Prototype' then cal = 'OVT_CAL';
else cal = 'DEFAULT';
run;
proc cpm date='02dec91'd data=widgcal out=scheddef
holidata=holidays daylength='08:00't
workday=workdata
calendar=calendar;
holiday holiday / holifin = holifin;
activity task;
duration days;
successor succ1 succ2 succ3;
run;
title2 'Project Schedule: Default calendar';
proc print;
var task days e_start e_finish l_start l_finish
t_float f_float;
run;
Output 2.10.4: Schedule using Default Calendar
Multiple Calendars |
Project Schedule: Default calendar |
Obs |
task |
days |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
F_FLOAT |
1 |
Approve Plan |
5.5 |
02DEC91:08:00:00 |
09DEC91:11:59:59 |
02DEC91:08:00:00 |
09DEC91:11:59:59 |
0.0 |
0.0 |
2 |
Drawings |
10.0 |
09DEC91:12:00:00 |
23DEC91:11:59:59 |
09DEC91:12:00:00 |
23DEC91:11:59:59 |
0.0 |
0.0 |
3 |
Anal. Market |
5.0 |
09DEC91:12:00:00 |
16DEC91:11:59:59 |
24JAN92:12:00:00 |
31JAN92:11:59:59 |
30.0 |
0.0 |
4 |
Write Specs |
4.5 |
09DEC91:12:00:00 |
13DEC91:15:59:59 |
17DEC91:08:00:00 |
23DEC91:11:59:59 |
5.5 |
5.5 |
5 |
Prototype |
15.0 |
23DEC91:12:00:00 |
17JAN92:11:59:59 |
23DEC91:12:00:00 |
17JAN92:11:59:59 |
0.0 |
0.0 |
6 |
Mkt. Strat. |
10.0 |
16DEC91:12:00:00 |
03JAN92:11:59:59 |
31JAN92:12:00:00 |
14FEB92:11:59:59 |
30.0 |
30.0 |
7 |
Materials |
10.0 |
17JAN92:12:00:00 |
31JAN92:11:59:59 |
17JAN92:12:00:00 |
31JAN92:11:59:59 |
0.0 |
0.0 |
8 |
Facility |
10.0 |
17JAN92:12:00:00 |
31JAN92:11:59:59 |
17JAN92:12:00:00 |
31JAN92:11:59:59 |
0.0 |
0.0 |
9 |
Init. Prod. |
10.0 |
31JAN92:12:00:00 |
14FEB92:11:59:59 |
31JAN92:12:00:00 |
14FEB92:11:59:59 |
0.0 |
0.0 |
10 |
Evaluate |
10.0 |
14FEB92:12:00:00 |
28FEB92:11:59:59 |
21FEB92:12:00:00 |
06MAR92:11:59:59 |
5.0 |
5.0 |
11 |
Test Market |
15.0 |
14FEB92:12:00:00 |
06MAR92:11:59:59 |
14FEB92:12:00:00 |
06MAR92:11:59:59 |
0.0 |
0.0 |
12 |
Changes |
5.0 |
06MAR92:12:00:00 |
13MAR92:11:59:59 |
06MAR92:12:00:00 |
13MAR92:11:59:59 |
0.0 |
0.0 |
13 |
Production |
0.0 |
13MAR92:12:00:00 |
13MAR92:12:00:00 |
13MAR92:12:00:00 |
13MAR92:12:00:00 |
0.0 |
0.0 |
14 |
Marketing |
0.0 |
14FEB92:12:00:00 |
14FEB92:12:00:00 |
13MAR92:12:00:00 |
13MAR92:12:00:00 |
20.0 |
20.0 |
|
Next PROC CPM
is invoked with the CALID statement identifying the variable CAL
in the Activity and Calendar data sets. Recall that the two activities,
`Production' and `Prototype', do not follow the default calendar.
The schedule displayed in Output 2.10.5 shows that,
due to longer working hours
for these two activities in the project, the scheduled finish date is
now March 9, at 10:00 a.m.
proc cpm date='02dec91'd data=widgcal out=schedmc
holidata=holidays daylength='08:00't
workday=workdata
calendar=calendar;
holiday holiday / holifin = holifin;
activity task;
duration days;
successor succ1 succ2 succ3;
calid cal;
run;
title2 'Project Schedule: Three Calendars';
proc print;
var task days cal e_: l_: t_float f_float;
run;
Output 2.10.5: Schedule using Three Calendars
Multiple Calendars |
Project Schedule: Three Calendars |
Obs |
task |
days |
cal |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
F_FLOAT |
1 |
Approve Plan |
5.5 |
DEFAULT |
02DEC91:08:00:00 |
09DEC91:11:59:59 |
02DEC91:08:00:00 |
09DEC91:11:59:59 |
0.00 |
0.00 |
2 |
Drawings |
10.0 |
DEFAULT |
09DEC91:12:00:00 |
23DEC91:11:59:59 |
09DEC91:12:00:00 |
23DEC91:11:59:59 |
0.00 |
0.00 |
3 |
Anal. Market |
5.0 |
DEFAULT |
09DEC91:12:00:00 |
16DEC91:11:59:59 |
20JAN92:10:00:00 |
27JAN92:09:59:59 |
25.75 |
0.00 |
4 |
Write Specs |
4.5 |
DEFAULT |
09DEC91:12:00:00 |
13DEC91:15:59:59 |
17DEC91:08:00:00 |
23DEC91:11:59:59 |
5.50 |
5.50 |
5 |
Prototype |
15.0 |
OVT_CAL |
23DEC91:12:00:00 |
13JAN92:09:59:59 |
23DEC91:12:00:00 |
13JAN92:09:59:59 |
0.00 |
0.00 |
6 |
Mkt. Strat. |
10.0 |
DEFAULT |
16DEC91:12:00:00 |
03JAN92:11:59:59 |
27JAN92:10:00:00 |
10FEB92:09:59:59 |
25.75 |
25.75 |
7 |
Materials |
10.0 |
DEFAULT |
13JAN92:10:00:00 |
27JAN92:09:59:59 |
13JAN92:10:00:00 |
27JAN92:09:59:59 |
0.00 |
0.00 |
8 |
Facility |
10.0 |
DEFAULT |
13JAN92:10:00:00 |
27JAN92:09:59:59 |
13JAN92:10:00:00 |
27JAN92:09:59:59 |
0.00 |
0.00 |
9 |
Init. Prod. |
10.0 |
DEFAULT |
27JAN92:10:00:00 |
10FEB92:09:59:59 |
27JAN92:10:00:00 |
10FEB92:09:59:59 |
0.00 |
0.00 |
10 |
Evaluate |
10.0 |
DEFAULT |
10FEB92:10:00:00 |
24FEB92:09:59:59 |
17FEB92:10:00:00 |
02MAR92:09:59:59 |
5.00 |
5.00 |
11 |
Test Market |
15.0 |
DEFAULT |
10FEB92:10:00:00 |
02MAR92:09:59:59 |
10FEB92:10:00:00 |
02MAR92:09:59:59 |
0.00 |
0.00 |
12 |
Changes |
5.0 |
DEFAULT |
02MAR92:10:00:00 |
09MAR92:09:59:59 |
02MAR92:10:00:00 |
09MAR92:09:59:59 |
0.00 |
0.00 |
13 |
Production |
0.0 |
PROD_CAL |
09MAR92:10:00:00 |
09MAR92:10:00:00 |
09MAR92:10:00:00 |
09MAR92:10:00:00 |
0.00 |
0.00 |
14 |
Marketing |
0.0 |
DEFAULT |
10FEB92:10:00:00 |
10FEB92:10:00:00 |
09MAR92:10:00:00 |
09MAR92:10:00:00 |
20.00 |
20.00 |
|
Now suppose that the engineer in charge of writing specifications
requests a seven-day vacation from
December 9, 1991.
How is the project completion time going to be affected? A new calendar,
Eng_cal, is defined that has the same work pattern as the default calendar,
but it also contains an extra vacation period. Output 2.10.6 displays
the data sets HOLIDATA and CALEDATA, which contain
information about the
new calendar. The fourth observation in the data set CALEDATA
has missing values for the variables _sun_, ...,
_sat_, indicating
that the calendar, Eng_cal, follows the same work pattern as the
default calendar.
Output 2.10.6: HOLIDATA and CALEDATA Data Sets
Multiple Calendars |
Holidays Data Set |
Obs |
holiday |
holifin |
holidur |
cal |
1 |
09DEC91 |
. |
7 |
Eng_cal |
2 |
25DEC91 |
27DEC91 |
. |
|
3 |
01JAN92 |
01JAN92 |
. |
|
Multiple Calendars |
Calendar Data Set |
Obs |
cal |
_sun_ |
_mon_ |
_tue_ |
_wed_ |
_thu_ |
_fri_ |
_sat_ |
1 |
DEFAULT |
holiday |
fullday |
fullday |
fullday |
fullday |
fullday |
holiday |
2 |
OVT_CAL |
holiday |
ovtday |
ovtday |
ovtday |
ovtday |
ovtday |
halfday |
3 |
PROD_CAL |
holiday |
s2 |
s1 |
s1 |
s1 |
s1 |
s3 |
4 |
Eng_cal |
|
|
|
|
|
|
|
|
Once again, in the following code, PROC GANTT is used to compare the
new calendar with the default calendar, as shown in Output 2.10.7.
Note that the breaks and holidays are marked with a solid fill pattern.
/* Create a data set to illustrate holidays with PROC GANTT */
data cals2;
e_start='2dec91:00:00'dt;
e_finish='19dec91:00:00'dt;
label cal ='Schedule Breaks / Holidays';
format e_start e_finish datetime16.;
length cal $8.;
cal='DEFAULT' ; output;
cal='Eng_cal' ; output;
run;
title2 'Breaks and Holidays for Eng_cal and the DEFAULT Calendar';
proc gantt data=cals2 graphics
calendar=caledata holidata=holidata
workday=workdata;
chart / interval=dtday mininterval=dthour skip=2
holiday=(holiday) holifin=(holifin) holidur=(holidur)
markbreak daylength='08:00't calid=cal
ref='2dec91:00:00'dt to '19dec91:00:00'dt by dtday
nojobnum nolegend increment=16 hpages=3;
id cal;
run;
Output 2.10.7: Difference Between Eng_cal and DEFAULT Calendar
The Activity data set is
modified to redefine the calendar for the task `Write Specs'.
PROC CPM is invoked, and Output 2.10.8 shows the new schedule obtained.
Note
the effect of the Engineer's vacation on the project completion time.
The project is now scheduled to finish at 10 a.m. on March 10, 1992;
in effect, the delay is only one day, even though the planned vacation
period is seven days. This is due to the fact that the activity
`Write Specs',
which follows the new calendar, had some slack time present in its
original schedule; however, this activity has now become critical.
data widgvac;
set widgcal;
if task = 'Write Specs' then cal = 'Eng_cal';
run;
proc cpm date='02dec91'd data=widgvac out=schedvac
holidata=holidata daylength='08:00't
workday=workdata
calendar=caledata;
holiday holiday / holifin = holifin holidur=holidur;
activity task;
duration days;
successor succ1 succ2 succ3;
calid cal;
run;
title2 'Project Schedule: Four Calendars';
proc print;
var task days cal e_: l_: t_float f_float;
run;
Output 2.10.8: Schedule Using Four Calendars
Multiple Calendars |
Project Schedule: Four Calendars |
Obs |
task |
days |
cal |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
F_FLOAT |
1 |
Approve Plan |
5.5 |
DEFAULT |
02DEC91:08:00:00 |
09DEC91:11:59:59 |
03DEC91:08:00:00 |
10DEC91:11:59:59 |
1.00 |
0.00 |
2 |
Drawings |
10.0 |
DEFAULT |
09DEC91:12:00:00 |
23DEC91:11:59:59 |
10DEC91:12:00:00 |
24DEC91:11:59:59 |
1.00 |
1.00 |
3 |
Anal. Market |
5.0 |
DEFAULT |
09DEC91:12:00:00 |
16DEC91:11:59:59 |
21JAN92:10:00:00 |
28JAN92:09:59:59 |
26.75 |
0.00 |
4 |
Write Specs |
4.5 |
Eng_cal |
18DEC91:08:00:00 |
24DEC91:11:59:59 |
18DEC91:08:00:00 |
24DEC91:11:59:59 |
0.00 |
0.00 |
5 |
Prototype |
15.0 |
OVT_CAL |
24DEC91:12:00:00 |
14JAN92:09:59:59 |
24DEC91:12:00:00 |
14JAN92:09:59:59 |
0.00 |
0.00 |
6 |
Mkt. Strat. |
10.0 |
DEFAULT |
16DEC91:12:00:00 |
03JAN92:11:59:59 |
28JAN92:10:00:00 |
11FEB92:09:59:59 |
26.75 |
26.75 |
7 |
Materials |
10.0 |
DEFAULT |
14JAN92:10:00:00 |
28JAN92:09:59:59 |
14JAN92:10:00:00 |
28JAN92:09:59:59 |
0.00 |
0.00 |
8 |
Facility |
10.0 |
DEFAULT |
14JAN92:10:00:00 |
28JAN92:09:59:59 |
14JAN92:10:00:00 |
28JAN92:09:59:59 |
0.00 |
0.00 |
9 |
Init. Prod. |
10.0 |
DEFAULT |
28JAN92:10:00:00 |
11FEB92:09:59:59 |
28JAN92:10:00:00 |
11FEB92:09:59:59 |
0.00 |
0.00 |
10 |
Evaluate |
10.0 |
DEFAULT |
11FEB92:10:00:00 |
25FEB92:09:59:59 |
18FEB92:10:00:00 |
03MAR92:09:59:59 |
5.00 |
5.00 |
11 |
Test Market |
15.0 |
DEFAULT |
11FEB92:10:00:00 |
03MAR92:09:59:59 |
11FEB92:10:00:00 |
03MAR92:09:59:59 |
0.00 |
0.00 |
12 |
Changes |
5.0 |
DEFAULT |
03MAR92:10:00:00 |
10MAR92:09:59:59 |
03MAR92:10:00:00 |
10MAR92:09:59:59 |
0.00 |
0.00 |
13 |
Production |
0.0 |
PROD_CAL |
10MAR92:10:00:00 |
10MAR92:10:00:00 |
10MAR92:10:00:00 |
10MAR92:10:00:00 |
0.00 |
0.00 |
14 |
Marketing |
0.0 |
DEFAULT |
11FEB92:10:00:00 |
11FEB92:10:00:00 |
10MAR92:10:00:00 |
10MAR92:10:00:00 |
20.00 |
20.00 |
|
Copyright © 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.