Counting the working or trading days within a calendar interval is a fairly common task. It typically entails exclusion of Saturdays, Sundays, and holidays. The Saturdays and Sundays can be readily identified using the WEEKDAY function. SAS has a HOLIDAY function, but it is not analogous to the WEEKDAY function.
A solution is to use rules to generate holiday lists.
The following example reflects United States Government holidays, but can easily be adapted to other rule sets. Note that holidays occurring on weekends are shifted to adjacent weekdays. Typically that is appropriate for applications requiring identification of trading days or working days.
The results for selected years:
Year HolidayName HoliDate 1971 New Year's Day Fri, Jan 1, 1971 Martin Luther King Day Mon, Jan 18, 1971 Presidents' Day Mon, Feb 15, 1971 Memorial Day Mon, May 31, 1971 Independence Day Mon, Jul 5, 1971 Labor Day Mon, Sep 6, 1971 Columbus Day Mon, Oct 11, 1971 Veterans Day Thu, Nov 11, 1971 Thanksgiving Day Thu, Nov 25, 1971 Christmas Fri, Dec 24, 1971 New Year's Eve Fri, Dec 31, 1971 1972 Martin Luther King Day Mon, Jan 17, 1972 Presidents' Day Mon, Feb 21, 1972 Memorial Day Mon, May 29, 1972 Independence Day Tue, Jul 4, 1972 Labor Day Mon, Sep 4, 1972 Columbus Day Mon, Oct 9, 1972 Veterans Day Fri, Nov 10, 1972 Thanksgiving Day Thu, Nov 23, 1972 Christmas Mon, Dec 25, 1972 2070 New Year's Day Wed, Jan 1, 2070 Martin Luther King Day Mon, Jan 20, 2070 Presidents' Day Mon, Feb 17, 2070 Memorial Day Mon, May 26, 2070 Independence Day Fri, Jul 4, 2070 Labor Day Mon, Sep 1, 2070 Columbus Day Mon, Oct 13, 2070 Veterans Day Tue, Nov 11, 2070 Thanksgiving Day Thu, Nov 27, 2070 Christmas Thu, Dec 25, 2070
The HOLIDAY function currently (as of SAS Version 9.2) recognizes only widely observed United States and Canadian holidays. Other holidays can be generated using the appropriate functions. For holidays observed on a fixed day of the week, such as Patriot's Day, use the NWKDOM function. For holidays with fixed dates, it's the MDY function. Examples:
The HOLIDAY function will generate any holiday it recognizes for any year which SAS recognizes. For example, note in the results above that Martin Luther King Day appears for 1970 and 1971 even though it was not adopted as an official holiday until 1986. Veteran's Day is another such case; from 1971 through 1977 it was observed on the fourth Monday in October before reverting in 1978 to the traditional November 11, yet the HOLIDAY function yields November 11 for all years. Whether these are problems depends on the time horizons of one's application. If necessary, conditional code can be added to adjust or suppress the incorrect results of the function.
Both the HOLIDAY and NWKDOM functions were introduced in Version 9.2. Generating fixed-date holidays for earlier versions is rather straightforward using the MDY function. See the example for St. Patrick's Day, above. Fixed-day-of-week holidays are a bit more complicated. Here are two examples:
In the first, Thanksgiving is defined as the start of the Thursday-to-Wednesday week which includes November 28. In the second, Memorial Day is defined as the start of the Monday-to-Sunday week which includes the last day of the month of May.
Easter presents a more difficult problem, since it is not defined within the context of the Gregorian calendar. One must instead turn to Computus. Here is a solution derived from the 1876 Nature article.
Given a HOLIDAYS data set (see above), one can call PROC CALENDAR to display it, as with
Consider the WEEKDAY date interval. It supports date interval computations which skip weekend days (by default, Saturday and Sunday; other definitions available to reflect local custom). Often one needs to refine that behavior by skipping weekday holidays and possibly unplanned weekday shutdowns.
SAS supports Custom Time Intervals for this purpose.
Suppose you have the HOLIDAYS data set (see above), and you want to establish a custom business day interval which will support dates from 2008 to 2010 inclusive. Start by generating a list of weekdays which include the specified 3-year span.
To generalize a bit, suppose that there were some unexpected business closures during those years. Record those in a separate data set.
Now complete the custom interval definition by excluding the holidays and other closure dates from the weekday enumeration.
The INTERVALDS= System Option implements and names the custom interval definition.
Here's an application example. It generates a list of business days, excluding weekends, holidays, and other closures.
Sometimes One Needs an Option with Unusual Dates provides code that combines the holiday function, PROC FCMP and the intervalds option to create an expanded holiday function (holiday_x) that includes Chinese, Islamic and Jewish holidays, as well as additional holidays and spelling variants.
Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.
If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website.
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.