5.4 Reading & Displaying Dates with Informats and Formats
Key Takeaways
- An informat tells SAS how to READ an external date expression into a numeric SAS date value; a format tells SAS how to DISPLAY that stored number.
- MMDDYY10., DDMMYY10., DATE9., YYMMDD10., and ANYDTDTE. are the informats most often needed to read common date expressions.
- The width in an informat is the count of raw characters to read: MMDDYY8. reads 10/31/26 while MMDDYY10. is required for 10/31/2026.
- The YEARCUTOFF= system option supplies the century for two-digit years and defaults to 1926 in SAS 9.4, so the window runs 1926-2025 and a two-digit 26 reads as 1926, not 2026.
- A date variable created by the INPUT function carries no format, so it prints as a bare day count until a FORMAT statement is applied.
5.4 Reading & Displaying Dates with Informats and Formats
Quick Answer: The content guide's date objective has three parts: explain how SAS stores dates, use SAS informats to read common date and time expressions, and use SAS date and time formats to specify how the values are displayed. An informat is an input instruction (
MMDDYY10.); a format is an output instruction (DATE9.). Both matter because the stored value is only a count of days since 1 January 1960.
1. Informat or Format? The One-Line Test
| Informat | Format | |
|---|---|---|
| Direction | External text into SAS | Stored value out to the reader |
| Used by | INPUT statement, INPUT() function, INFORMAT statement, PROC IMPORT | FORMAT statement, PUT() function, PUT statement, every reporting procedure |
| Changes the stored value? | Yes — it creates the number | No — display only |
| Typical example | mmddyy10. reading 10/31/2026 into 24775 | date9. displaying 24775 as 31OCT2026 |
Reading "31OCT2026" with DATE9. and displaying 24775 with DATE9. are different operations that happen to share a name. SAS resolves the ambiguity by position: whatever follows a variable in an INPUT statement is an informat, whatever follows it in a FORMAT statement is a format.
2. Informats That Read Common Date Expressions
| Informat | Reads values like | Notes |
|---|---|---|
MMDDYY8. / MMDDYY10. | 10/31/26, 10/31/2026 | US month-day-year; separators may be /, -, or a blank |
DDMMYY8. / DDMMYY10. | 31/10/26, 31/10/2026 | European day-month-year |
DATE7. / DATE9. | 31OCT26, 31OCT2026 | The SAS-native ddMMMyyyy form |
YYMMDD8. / YYMMDD10. | 26-10-31, 2026-10-31 | ISO 8601 ordering |
MONYY5. / MONYY7. | OCT26, OCT2026 | Returns the first day of that month |
JULIAN5. / JULIAN7. | 26305, 2026305 | Year plus day-of-year |
ANYDTDTE. | Almost any of the above | SAS infers the layout; ambiguous for values such as 03/04/2026 |
TIME8. | 14:30:00 | Seconds past midnight |
DATETIME18. / DATETIME20. | 31OCT2026:14:30:00 | Seconds since midnight on 01JAN1960 |
data work.read_dates;
infile datalines truncover;
input @1 us_date mmddyy10.
@12 iso_date yymmdd10.
@23 sas_date date9.
@33 clock time8.;
format us_date iso_date sas_date date9. clock time8.;
datalines;
10/31/2026 2026-10-31 31OCT2026 14:30:00
;
run;
All four raw strings become numbers. us_date, iso_date, and sas_date all hold 24775; clock holds 52200.
The INPUT Function Does the Same Job in Memory
data work.convert_dates;
set work.raw_strings; /* HireText is character */
HireDate = input(HireText, mmddyy10.); /* numeric SAS date */
format HireDate date9.; /* without this it prints 24775 */
run;
Exam Trap: a variable created by
INPUT()has no format attached. It is a perfectly correct SAS date value that prints as a bare integer until aFORMATstatement is applied. A question showing24775where the candidate expected31OCT2026is testing exactly this distinction.
3. Informat Width Rules
The w in MMDDYYw. is the number of raw characters to read, not the number of digits in the year.
| Raw value | Correct informat | Wrong informat and its result |
|---|---|---|
10/31/26 | MMDDYY8. | MMDDYY10. may consume characters belonging to the next field |
10/31/2026 | MMDDYY10. | MMDDYY8. reads only 10/31/20, giving 31 October 2020 |
31OCT2026 | DATE9. | DATE7. reads 31OCT20 — the year becomes 2020 |
A too-narrow informat rarely raises an error. It quietly produces a wrong date, which is the textbook definition of a logic error.
Two-Digit Years and YEARCUTOFF=
When an informat receives a two-digit year, the YEARCUTOFF= system option supplies the century. It sets the first year of a rolling 100-year window and defaults to 1926 in SAS 9.4, so the window runs 1926 through 2025.
options yearcutoff=1926; /* the SAS 9.4 default: window = 1926-2025 */
data work.century;
d1 = input('10/31/26', mmddyy8.); /* 31OCT1926 */
d2 = input('10/31/40', mmddyy8.); /* 31OCT1940 */
d3 = input('10/31/20', mmddyy8.); /* 31OCT2020 */
format d1 d2 d3 date9.;
run;
Within the 1926-2025 window, two-digit years 26 through 99 map to 1926-1999 and 00 through 25 map to 2000-2025. A file that records the year 2026 as 26 therefore imports as 1926 unless you raise the cutoff:
options yearcutoff=1950; /* window becomes 1950-2049 */
data _null_;
d = input('10/31/26', mmddyy8.); /* now 31OCT2026 */
put d = date9.;
run;
The dependable defence is to demand four-digit years in every source file rather than reasoning about the window at all.
4. Formats That Display Date Values
| Format | 24775 displays as | Typical use |
|---|---|---|
DATE9. | 31OCT2026 | The SAS default reporting form |
MMDDYY10. | 10/31/2026 | US business reports |
DDMMYY10. | 31/10/2026 | European reports |
YYMMDD10. | 2026-10-31 | ISO output; sorts correctly as text |
WORDDATE18. | October 31, 2026 | Narrative headings |
WEEKDATE29. | Saturday, October 31, 2026 | Dashboards |
MONYY7. | OCT2026 | Monthly grouping |
YEAR4. | 2026 | Annual grouping |
TIME8. | 14:30:00 (from 52200) | Clock times |
DATETIME20. | 31OCT2026:14:30:00 | Timestamps |
data work.display_variants;
d = '31OCT2026'd;
run_dt = '31OCT2026:14:30:00'dt;
format d date9. run_dt datetime20.;
run;
proc print data=work.display_variants;
format d worddate18.; /* overrides the permanent format for this step only */
run;
A FORMAT statement inside a DATA step attaches the format permanently; inside a PROC step it applies for that step alone. Because formats never alter the stored number, arithmetic, sorting, INTCK, and INTNX continue to operate on the underlying day count no matter how the value is displayed.
Exam Tip: the width of a format must be wide enough for the result.
DATE7.applied to31OCT2026prints31OCT26, and a badly undersized format prints asterisks. When output shows unexpected***, suspect the format width first.
A character variable HireText holds '03/15/2026'. Which statement creates a numeric SAS date variable that prints as 15MAR2026?
A raw file contains 12/25/2026 and the program reads it with input EventDate mmddyy8.;. What date results?
What is the essential difference between a SAS informat and a SAS format?
A DATA step creates HireDate with the INPUT function and MMDDYY10., but PROC PRINT shows values such as 24775 instead of calendar dates. What is wrong?