By Robin High (robinh@darkwing.uoregon.edu)
The year 2000 has arrived, and if you're a SAS user you may wonder if programs that use dates are going to give you correct results. This article discusses how SAS handles the Y2K dilemma.
The good news is that all versions of the SAS system currently in use correctly represent dates from 1582 A.D. to 20,000 A.D. Leap years, century, and fourth-century adjustments are made automatically.
SAS stores dates internally as an integer: the number of days since January 1, 1960 (the reference point). Dates prior to 01/01/1960 are stored as negative numbers. Using a FORMAT statement, you can print the date value in a wide variety of date lists, e.g.,
DATA dt; FORMAT date mmddyy10.; i= -365; date=i; OUTPUT dt; i= 0; date=i; OUTPUT dt; i= 366; date=i; OUTPUT dt;i=14610; date=i; OUTPUT dt;PROC PRINT DATA=dt;
VAR i date; RUN;
PROC PRINT produces the following output:
| OBS | I | DATE |
| 1 | -365 | 01/01/1959 |
| 2 | 0 | 01/01/1960 |
| 3 | 366 | 01/01/1961 |
| 4 | 14610 | 01/01/2000 |
If you always read date variables from external data files with 4-digit years, you don't need to read any further in this article. SAS reads and processes all 4-digit years properly and prints them the way you expect as long as you choose the appropriate date format.
However, if you habitually use date formats with 2-digit years like 12/31/99, the information in this article is essential now that we live in the year 2000.
There are three primary ways to avoid a Y2K glitch in a SAS program:
1. Always use 4-digit years such as 12/31/1999 in external data files. This is the most important and effective way to ensure that your programs work properly.
2. Use SAS date formats (not character formats) that specify 4-digit years for input and printing. Existing SAS code that formats dates with 2-digit years should be edited to ensure date values are processed correctly.
3. If you absolutely must use 2-digit year values, invoke the YEARCUTOFF= system option in an OPTIONS statement (see description below).
The Y2K problem is a legitimate concern in SAS whenever you have an incomplete year specification in an external data file (e.g., using 99 to represent 1999). However, you can still use the 2-digit year format in SAS date values if you know how the "YEARCUTOFF" option works.
First, determine the default value of YEARCUTOFF by running a SAS program with the following command:
PROC OPTIONS OPTION=yearcutoff; RUN;
On Darkwing and Oregon, the SAS log file reads:
YEARCUTOFF=1910 Cutoff year for DATE7. informat
which indicates that 1910 is the default cutoff value. This default value could change in the future, so it's prudent to check it occasionally.
If you want to change the default YEARCUTOFF value to specify some other year as the beginning value in a 100-year span, include the specification with a system OPTIONS statement anywhere in the program prior to the use of the date values. Valid values for the specified first year of the 100-year span can range from a low of 1582 to a maximum of 19900. Your chosen value can be written into an OPTIONS statement as shown below.
Example 1:
OPTIONS yearcutoff=1920;
This OPTIONS statement includes YEARCUTOFF=1920, which specifies that 1920 is the first year of a 100-year span of a 2-digit year. In this case, the 100-year span ranges from 1920-2019, inclusive:
| 1900.. | 1920... | 1930..... | 2000... | 2010... | 2019... | 2025 |
| | | | | |||||
|
100 Year Span |
||||||
This means a 2-digit year in a date value such as 12/31/15 represents December 31, 2015 and 12/31/22 represents December 31, 1922.
Example 2: Dates with both 2-digit and 4-digit years. In the next example, note the YEARCUTOFF= option is now set to 1930. The dividing year is changed to 1930 so that 2-digit years from 30-99 are treated as 1930-1999 and years coded as 00-29 are treated as 2000-2029:
OPTIONS yearcutoff=1930;DATA schedule; FORMAT jobid $char4. projdate mmddyy10.; INPUT @1 jobid $ @6 projdate mmddyy10.; CARDS; A100 01/15/35 A110 03/15/2035 A200 01/30/16 B100 02/05/00 B200 06/15/2000 ; PROC PRINT DATA=schedule; RUN;
PROC PRINT produces this output:
| OBS | JOBID | PROJDATE |
| 1 | A100 | 01/15/1935 |
| 2 | A110 | 03/15/2035 |
| 3 | A200 | 01/30/2016 |
| 4 | B100 | 02/05/2000 |
| 5 | B200 | 06/15/2000 |
When you compare observations 1 and 2 in the data (following CARDS; in the data step) and the output listing, notice the difference in the interpreted value of a year when you specify a 2-digit year instead of a 4-digit year.
In the input data observation, 1 has a 2-digit year of 35, and observation 2 has a 4-digit year of 2035. Since YEARCUTOFF=1930, the 2-digit year 35 defaults to 1935. The 4-digit year 2035 in observation 2 is unaffected by the YEARCUTOFF= option.
Observation 3 is read with a 2-digit year (16) that defaults to 2016 based on the value specified in YEARCUTOFF (=1930).
Observations 4 and 5 show similar results. In the data file, observation 4 specifies a 2-digit year of 00; and observation 5, a 4-digit year of 2000. Because the value of YEARCUTOFF=1930, the resulting years for the two observations are the same on the printed output. These results emphasize that specifying a 2-digit year may or may not result in the preferred century prefix if you aren't aware of the YEARCUTOFF value that applies.
The YEARCUTOFF= option does not affect existing dates that are currently in your SAS datasets. Since a date is stored as an integer number (see Example 1), the way it is interpreted in a program is unaffected. The way it prints to a listing is determined only by the FORMAT statement you choose.
Date functions in the SAS System that use 2-digit years are also affected by the value of the YEARCUTOFF= option. For example, suppose you use the MDY and YEAR functions with a 2-digit value of 15 as the year parameter, e.g.,
yy=15; yyyy=YEAR(MDY(12,31,yy));
The new variable yyyy will equal 1915 or 2015, depending on the existing value of YEARCUTOFF.
Writing dates with 2-digit years to external data files. Suppose you want to write a SAS date equivalent to January 15, 2001, to an external data source with a 2-digit year. Using the MMDDYY8. format with YEARCUTOFF=1920, a 2-digit year of 01 would appear. Ten years ago, others using the same data could easily assume the century prefix, but during the 21st century the century prefix of the 2-digit year will not be as clear. Moral: always check the setting of the YEARCUTOFF= option!
For additional details on how the YEARCUTOFF= option works and how to determine the optimum settings for your applications, refer to the document "Using the YEARCUTOFF= Option to Interpret 2-digit Years in Your SAS Applications," available online at http://www.sas.com/techsup/download/technote/ts618.html
SAS is well prepared to handle dates in the 21st century. You should have no problems if you
1. always use dates with 4-digit years in your external data sources when using date functions or writing to external files
or, if that's not possible,
2. determine the optimal setting for the YEARCUTOFF= option in your working environment