The CPM Procedure

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 provide 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.

Default Calendar

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 non-working 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.

WORKDATA 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.

CALEDATA Data Set

The Calendar data set defines specific calendars using the names of the shift variables in the Workday data set. You can 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\times 4=32$ hours or $7\times 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 section WORKDATA Data Set. 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. The Calendar data set can be used to define the default calendar also.

HOLIDATA Data Set

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 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 24DEC03 to 26DEC03 (both days inclusive). 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_

       24DEC03        .          26DEC03       .
       01JAN04        1             .          1
       19JAN04        .             .          2
       29JAN04        3             .          2
       29JAN04        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 4.7.

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 29, 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 4.7: Holiday Definitions

Calendar

Holiday Start

Holiday End

0

24DEC03:09:00

26DEC03:16:59:59

1

24DEC03:09:00

26DEC03:07:59:59

 

01JAN04:00:00

01JAN04:07:59:59

2

24DEC03:09:00

26DEC03:16:59:59

 

19JAN04:09:00

19JAN04:16:59:59

 

29JAN04:09:00

02FEB04:16:59:59

3

24DEC03:09:00

26DEC03:16:59:59

 

29JAN04:09:00

31JAN04:16:59:59


You can use the GANTT procedure to visualize the breaks and holidays for the different calendar. Figure 4.4 shows all the breaks and holidays for the period between Christmas and New Year. Holidays and breaks are denoted by *. Likewise, Figure 4.5 shows the vacation periods in January for calendars '2' and '3'.

Figure 4.4: Christmas and New Year Holidays for Multiple Calendars

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   |*********--------****************--------********************|                 
                     -+-----------+-----------+-----------+-----------+-----------+-                 



Christmas and New Year Holidays

            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            
           -+-----------+-----------+-----------+-----------+-----------+-----------+-               
           |*********************************************************************----|               
           |*******************************************************************----**|               
           |*************************************************************************|               
           |*********************************************************************----|               
           -+-----------+-----------+-----------+-----------+-----------+-----------+-               



Christmas and New Year Holidays

            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            
           -+-----------+-----------+-----------+-----------+-----------+-----------+-               
           |-----****************--------****************--------****************----|               
           |*******************************************----*----***************----*-|               
           |*********************************************--------****************----|               
           |-----****************--------****************--------****************----|               
           -+-----------+-----------+-----------+-----------+-----------+-----------+-               



Christmas and New Year Holidays

            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 4.5: Vacation Time for Calendars 2 and 3

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   |*********--------****************--------****************--------********|           
               -+-----------+-----------+-----------+-----------+-----------+-----------+-           



Vacation Times for Calendars 2 and 3

      JAN         JAN         JAN         JAN         JAN         JAN         JAN         JAN        
      21          21          22          22          23          23          24          24         
      00:00       12:00       00:00       12:00       00:00       12:00       00:00       12:00      
     -+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-         
     |*********--------****************--------****************--------********************|         
     |*********--------****************--------****************--------****************----|         
     -+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-         



Vacation Times for Calendars 2 and 3

      JAN         JAN         JAN         JAN         JAN         JAN         JAN         JAN        
      24          25          25          26          26          27          27          28         
      12:00       00:00       12:00       00:00       12:00       00:00       12:00       00:00      
     -+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-         
     |*********************************************--------****************--------********|         
     |-----****************--------****************--------****************--------********|         
     -+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-         



Vacation Times for Calendars 2 and 3

      JAN         JAN         JAN         JAN         JAN         JAN         JAN         JAN        
      28          28          29          29          30          30          31          31         
      00:00       12:00       00:00       12:00       00:00       12:00       00:00       12:00      
     -+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-         
     |*********--------********************************************************************|         
     |*********--------********************************************************************|         
     -+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-         



Vacation Times for Calendars 2 and 3

      JAN         FEB         FEB         FEB         FEB         FEB         FEB         FEB        
      31          01          01          02          02          03          03          04         
      12:00       00:00       12:00       00:00       12:00       00:00       12:00       00:00      
     -+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-         
     |*********************************************************************--------********|         
     |*********************--------****************--------****************--------********|         
     -+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-