SAS 9.1.3 Language Reference: Concepts, Third Edition, Volumes 1 and 2
About SAS Date, Time, and Datetime Values
Definitions
SAS date value |
is a value that represents the number of days between January 1, 1960, and a specified date. SAS can perform calculations on dates ranging from A.D. 1582 to A.D. 19,900. Dates before January 1, 1960, are negative numbers; dates after are positive numbers .
| |
SAS time value |
is a value representing the number of seconds since midnight of the current day. SAS time values are between 0 and 86400. | |
SAS datetime value |
is a value representing the number of seconds between January 1, 1960 and an hour /minute/second within a specified date. |
The following figure shows some dates written in calendar form and as SAS date values.
Two-Digit and Four-Digit Years
SAS software can read two-digit or four-digit year values. If SAS encounters a two-digit year, the YEARCUTOFF= option can be used to specify which century within a 100 year span the two-digit year should be attributed to. For example, YEARCUTOFF=1950 means that two-digit years 50 through 99 correspond to 1950 through 1999, while two-digit years 00 through 49 correspond to 2000 through 2049. Note that while the default value of the YEARCUTOFF= option in Version 8 of the SAS System is 1920, you can adjust the YEARCUTOFF= value in a DATA step to accommodate the range of date values you are working with at the moment. To correctly handle 2-digit years representing dates between 2000 and 2099, you should specify an appropriate YEARCUTOFF= value between 1901 and 2000. For more information, see the "YEARCUTOFF= System Option" in SAS Language Reference: Dictionary .
The Year 2000
Using the YEARCUTOFF= System Option
SAS software treats the year 2000 like any other leap year. If you use two-digit year numbers for dates, you'll probably need to adjust the default setting for the YEARCUTOFF= option to work with date ranges for your data, or switch to four-digit years. The following program changes the YEARCUTOFF= value to 1950. This change means that all two digit dates are now assumed to fall in the 100-year span from 1950 to 2049.
options yearcutoff=1950; data _null_; a='26oct02'd; put 'SAS date='a; put 'formatted date='a date9.; run;
The PUT statement writes the following lines to the SAS log:
SAS date=15639 formated date=26OCT2002
Note | Whenever possible, specify a year using all four digits. Most SAS date and time language elements support four digit year values. |
Example: How YEARCUTOFF= Affects Two and Four-Digit Years
The following example shows what happens with data that contains both two and four-digit years. Note how the YEARCUTOFF= option is set to 1920.
options yearcutoff=1920 nodate pageno=1 linesize=80 pagesize=60; data schedule; input @1 jobid $ @6 projdate mmddyy10.; datalines; A100 01/15/25 A110 03/15/2025 A200 01/30/96 B100 02/05/00 B200 06/15/2000 ; proc print data=schedule; format projdate mmddyy10.; run;
The resulting output from the PROC PRINT statement looks like this:
Output 8.1: Output from The Previous DATA Step Showing 4-Digit Years That Result from Setting YEARCUTOFF= to 1920
|
The SAS System 1 Obs jobid projdate 1 A100 01/15/1925 2 A110 03/15/2025 3 A200 01/30/1996 4 B100 02/05/2000 5 B200 06/15/2000
|
Here are some facts to note in this example:
-
In the datalines in the DATA step, the first record contains a two-digit year of 25, and the second record contains a four-digit year of 2025. Because the YEARCUTOFF= system option is set to 1920, the two-digit year defaults to a year in the 1900s in observation number 1. The four-digit year in observation number 2 is unaffected by the YEARCUTOFF= option.
-
The third record is similar to the first and defaults to a year in the 1900s based on the value of YEARCUTOFF=.
-
The output from records 4 and 5 shows results that are similar to records 1 and 2. The fourth record specifies a two-digit year of 00, and the fifth one specifies a four-digit year of 2000. Because of the value of the YEARCUTOFF= option, the years in the two resulting observations are the same.
As you can see, specifying a two-digit year may or may not result in the intended century prefix. The optimal value of the YEARCUTOFF= option depends on the range of the dates that you are processing.
In Releases 6.06 through 6.12 of SAS, the default value for the YEARCUTOFF= system option is 1900; in Version 7 and Version 8, the default value is 1920.
For more information on how SAS handles dates, see the section on dates, times and datetime values.
Practices That Help Ensure Date Integrity
The following practices help ensure that your date values are correct during all the conversions that occur during processing:
-
Store dates as SAS date values, not as simple numeric or character values.
-
Use the YEARCUTOFF= system option when converting two-digit dates to SAS date values.
-
Examine sets of raw data coming into your SAS process to make sure that any dates containing two-digit years will be correctly interpreted by the YEARCUTOFF= system option. Look out for
-
two-digit years that are distributed over more than a 100-year period. For dates covering more than a 100-year span, you must either use four digit years in the data, or use conditional logic in a DATA step to interpret them correctly.
-
two-digit years that need an adjustment to the default YEARCUTOFF= range. For example, if the default value for YEARCUTOFF= in your operating environment is 1920 and you have a two-digit date in your data that represents 1919, you will have to adjust your YEARCUTOFF= value downward by a year in the SAS program that processes this value.
-
-
Make sure that output SAS data sets represent dates as SAS date values.
-
Check your SAS programs to make sure that formats and informats that use two-digit years, such as DATE7., MMDDYY6., or MMDDYY8., are reading and writing data correctly.
Note | The YEARCUTOFF= option has no effect on dates that are already stored as SAS date values. |
Working with SAS Dates and Times
Informats and Formats
The SAS System converts date, time and datetime values back and forth between calendar dates and clock times with SAS language elements called formats and informats .
-
Formats present a value, recognized by SAS, such as a time or date value, as a calendar date or clock time in a variety of lengths and notations.
-
Informats read notations or a value, such as a clock time or a calendar date, which may be in a variety of lengths, and then convert the data to a SAS date, time, or datetime value.
Date and Time Tools by Task
The following table correlates tasks with various SAS System language elements that are available for working with time and date data.
To do this | Use this | List | Input | Result |
---|---|---|---|---|
Write SAS date values in recognizable forms | Date formats | DATE w. | 14686 | 17MAR00 |
DATE9. | 14686 | 17MAR2000a | ||
DAY w. | 14686 | 17 | ||
DDMMYY w. | 14686 | 17/03/00 | ||
DDMMYY10. | 14686 | 17/03/2000 | ||
DDMMYYB w. | 14686 | 17 03 00 | ||
DDMMYYB10. | 14686 | 17 03 2000 | ||
DDMMYYC w. | 14686 | 17:03:20 | ||
DDMMYYC10. | 14686 | 17:03:2000 | ||
DDMMYYD w. | 14686 | 17-03-00 | ||
DDMMYYD10. | 14686 | 17-03-2000 | ||
DDMMYYN w. | 14686 | 17MAR00 | ||
DDMMYYN10 | 14686 | 17MAR2000 | ||
DDMMYYP w. | 14686 | 17.03.00 | ||
DDMMYYP10. | 14686 | 17.03.2000 | ||
DDMMYYS w. | 14686 | 17/03/00 | ||
DDMMYYS10. | 14686 | 17/03/2000 | ||
DOWNAME. | 14686 | Friday | ||
JULDAY w. | 14686 | 77 | ||
JULIAN w. | 14686 | 00077 | ||
MMDDYY w. | 14686 | 03/17/00 | ||
MMDDYY10. | 14686 | 03/17/2000 | ||
MMDDYYB w. | 14686 | 03 17 00 | ||
MMDDYYB10. w. | 14686 | 03 17 2000 | ||
MMDDYYC w. | 14686 | 03:17:00 | ||
MMDDYYC10 | 14686 | 03:17:2000 | ||
MMDDYYD w. | 14686 | 03-17-00 | ||
MMDDYYD10. | 14686 | 03-17-2000 | ||
MMDDYYN w. | 14686 | 031700 | ||
MMDDYYN10. | 14686 | 03172000 | ||
MMDDYYP | 14686 | 03.17.00 | ||
MMDDYYP10. | 14686 | 03.17.2000 | ||
MMDDYYS | 14686 | 03/17/00 | ||
MMDDYYS10. | 14686 | 03/17/2000 | ||
MMYY. xw. | 14686 | 03M2000 | ||
MMYYC w. | 14686 | 03:2000 | ||
MMYYD. | 14686 | 03-2000 | ||
MMYYN. | 14686 | 032000 | ||
MMYYP. | 14686 | 03.2000 | ||
MMYYS. | 14686 | 03/2000 | ||
MONNAME. | 14686 | March | ||
MONTH. | 14686 | 3 | ||
MONYY. | 14686 | MAR2000 | ||
PDJULG w. | 14686 | 2000077F | ||
PDJULI w. | 14686 | 0100077F | ||
QTR w. | 14686 | 1 | ||
QTRR w. | 14686 | I | ||
TIME w.d | 14686 | 4:04:46 | ||
TIMEAMPM w.d | 14686 | 4:04:46 AM | ||
TOD | 14686 | 4:04:46 | ||
WEEKDATE w. | 14686 | Friday, March 17, 2000 | ||
WEEKDAY w. | 14686 | 6 | ||
WORDDATE. w. | 14686 | March 17, 2000 | ||
WORDDATX w. | 14686 | 17 MARCH 2000 | ||
YEAR w. | 14686 | 2000 | ||
YYMM w. | 14686 | 2000M03 | ||
YYMMC w. | 14686 | 2000:03 | ||
YYMMDD w. | 14686 | 2000-03 | ||
YYMMP w. | 14686 | 2000.03 | ||
YYMMS. | 14686 | 2000/03 | ||
YYMMN. | 14686 | 200003 | ||
YYMMDD w. | 14686 | 00-03-17 | ||
YYMON. | 14686 | 2000MAR | ||
YYQ xw. | 14686 | 2000Q1 | ||
YYQC w. | 14686 | 2000:1 | ||
YYQD w. | 14686 | 2000-1 | ||
YYQP w. | 14686 | 2000.1 | ||
YYQS w. | 14686 | 2000/1 | ||
YYQN w. | 14686 | 20001 | ||
YYQR w. | 14686 | 2000QI | ||
YYQRC w. | 14686 | 2000:I | ||
YYQRD w. | 14686 | 2000-I | ||
YYQRP w.w. | 14686 | 2000.I | ||
YYQRS w. | 14686 | 2000/I | ||
YYQRN w. | 14686 | III |
To do this | Use this | List | Input | Result |
---|---|---|---|---|
Date Tasks | ||||
Read calendar dates as SAS date | Date informats | DATE w. | 17MAR2000 | 14686 |
Note: YEARCUTOFF=1920 | ||||
DATE9. | 17MAR2000 | 14686 | ||
DDMMYY w. | 170300 | 14686 | ||
DDMMYY8. | 17032000 | 14686 | ||
JULIAN w. | 0077 | 14686 | ||
JULIAN7. | 2000077 | 14686 | ||
MMDDYY w. | 031700 | 14686 | ||
MMDDYY10. | 03172000 | 14686 | ||
MONYY w. | MAR00 | 14670 | ||
YYMMDD w. | 000317 | 14686 | ||
YYMMDD10. | 20000317 | 14686 | ||
YYQ w. | 00Q1 | 14610 | ||
Create date values from pieces | Date functions | DATEJUL | 2000077 | 14686 |
DATETIME | '17MAR2000'D, | 1268870400 | ||
00,00,00 | ||||
TIME | 14,45,32 | 53132 | ||
MDY | 03,17,00 | 14686 | ||
MDY | 03,17,2000 | 14686 | ||
YYQ | 00,1 | 14610 | ||
Extract a date from a datetime value | Date functions | DATEPART | '17MAR00:00:00 'DT | 14686 |
Return today's date as a SAS date | Date functions | DATE() or TODAY() (equivalent) | ( ) | SAS date for |
Extract calendar dates from SAS | Date functions | DAY | 14686 | 17 |
HOUR | 14686 | 4 | ||
JULDATE | 14686 | 77 | ||
JULDATE7 | 14686 | 2000077 | ||
MINUTE | 14686 | 4 | ||
MONTH | 14686 | 3 | ||
QTR | 14686 | 3 | ||
SECOND | 14686 | 46 | ||
WEEKDAY | 14686 | 6 | ||
YEAR | 14686 | 2000 | ||
Write a date as a constant in an expression | SAS date constant | 'ddmmmyy' d or 'ddmmmyyyy' | '17mar00'd
'17mar2000'd | 14686 |
Write today's date as a string | SYSDATE automatic macro variable | SYSDATE | &SYSDATE | Date at time of SAS initialization in DDMMMYY |
SYSDATE9 | SYSDATE9 | &SYSDATE9 | Date at time of SAS initialization in DDMMMYYYY | |
Time Tasks | ||||
Write SAS time values as time values | time formats | HHMM. | 53132 | 14:46 |
HOUR. | 53132 | 15 | ||
MMSS. | 53132 | 885 | ||
TIME. | 53132 | 14:45:32 | ||
TOD. | 53132 | 14:45:32 | ||
Read time values as SAS time values | Time informats | TIME | 14:45:32 | 53132 |
Write the current time as a string | SYSTIME automatic macro variable | SYSTIME | &SYSTIME | Time at moment of execution in HH:MM |
Return the current time of day as a SAS time value | Time functions | TIME( ) | ( ) | SAS time value at moment of execution in NNNNN.NN |
Return the time part of a SAS datetime value | Time functions | TIMEPART | SAS datetime value in NNNNNNNNNN.N | SAS time value part of date value in NNNNN.NN |
Datetime Tasks | ||||
Write SAS datetime values as datetime values | Datetime formats | DATEAMPM | 1217083532 | 26JUL98:02:45 PM |
DATETIME | 1268870400 | 17MAR00:00:00 :00 | ||
Read datetime values as SAS datetime values | Datetime informats | DATETIME | 17MAR00:00:00:00 | 1268870400 |
Return the current date and time of day as a SAS datetime value | Datetime functions | DATETIME() | () | SAS datetime value at moment of execution in NNNNNNNNNN.N |
Interval Tasks | ||||
Return the number of specified time intervals that lie between the two date or datetime values | Interval functions | INTCK | week 2 01aug60 01jan01 | 1055 |
Advances a date, time, or datetime value by a given interval, and returns a date, time, or datetime value | Interval functions | INTNX | day 14086 01jan60 | 14086 |
The SAS System also supports international formats and informats that are equivalent to some of the most commonly used English-language date formats and informats. For details, see the SAS formats and informats in SAS Language Reference: Dictionary .
Examples
Example 1: Displaying Date, Time, and Datetime Values as Recognizable Dates and Times
The following example demonstrates how a value may be displayed as a date, a time, or a datetime. Remember to select the SAS language element that converts a SAS date, time, or datetime value to the intended date, time or datetime format. See the previous tables for examples.
Notes |
|
This program uses the DATETIME, DATE and TIMEAMPM formats to display the value 86399 to a date and time, a calendar date, and a time.
data test; options nodate pageno=1 linesize=80 pagesize=60; Time1=86399; format Time1 datetime.; Date1=86399; format Date1 date.; Time2=86399; format Time2 timeampm.; run; proc print data=test; title 'Same Number, Different SAS Values'; footnote1 'Time1 is a SAS DATETIME value'; footnote2 'Date1 is a SAS DATE value'; footnote3 'Time2 is a SAS TIME value'.; run;
Output 8.2: Datetime, Date and Time Values for 86399
|
Same Number, Different SAS Values 1 Obs Time1 Date1 Time2 1 01JAN60:23:59:59 20JUL96 11:59:59 PM Time1 is a SAS DATETIME value Date1 is a SAS DATE value Time2 is a SAS TIME value.
|
Example 2: Reading, Writing, and Calculating Date Values
This program reads four regional meeting dates and calculates the dates on which announcements should be mailed.
data meeting; options nodate pageno=1 linesize=80 pagesize=60; input region $ mtg : mmddyy8.; sendmail=mtg-45; datalines; N 11-24-99 S 12-28-99 E 12-03-99 W 10-04-99 ; proc print data=meeting; format mtg sendmail date9.; title 'When To Send Announcements'; run;
Output 8.3: Calculated Date Values: When to Send Mail
|
When To Send Announcements Obs region mtg sendmail 1 N 24NOV1999 10OCT1999 2 S 28DEC1999 13NOV1999 3 E 03DEC1999 19OCT1999 4 W 04OCT1999 20AUG1999
|