The Essential Guide To SAS Dates And Times Derek Morgan

Derek%20Morgan%20The%20Essential%20Guide%20to%20SAS%20Dates%20and%20Times

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 176

DownloadThe Essential Guide To SAS Dates And Times Derek Morgan
Open PDF In BrowserView PDF
SAS Press

The Essential Guide to

SAS Dates and Times
®

Derek P. Morgan

The correct bibliographic citation for this manual is as follows: Morgan, Derek P. 2006. The Essential Guide
®
to SAS Dates and Times. Cary, NC: SAS Institute Inc.
®

The Essential Guide to SAS Dates and Times
Copyright © 2006, SAS Institute Inc., Cary, NC, USA
ISBN-13: 978-1-59047-884-4
ISBN-10: 1-59047-884-3
All rights reserved. Produced in the United States of America.
For a hard-copy book: No part of this publication may be reproduced, stored in a retrieval system, or
transmitted, in any form or by any means, electronic, mechanical, photocopying, or otherwise, without the
prior written permission of the publisher, SAS Institute Inc.
For a Web download or e-book: Your use of this publication shall be governed by the terms established by
the vendor at the time you acquire this publication.
U.S. Government Restricted Rights Notice: Use, duplication, or disclosure of this software and related
documentation by the U.S. government is subject to the Agreement with SAS Institute and the restrictions set
forth in FAR 52.227-19, Commercial Computer Software-Restricted Rights (June 1987).
SAS Institute Inc., SAS Campus Drive, Cary, North Carolina 27513.
1st printing, June 2006
SAS Publishing provides a complete selection of books and electronic products to help customers use SAS
software to its fullest potential. For more information about our e-books, e-learning products, CDs, and hardcopy books, visit the SAS Publishing Web site at support.sas.com/pubs or call 1-800-727-3228.
SAS® and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS
Institute Inc. in the USA and other countries. ® indicates USA registration.
Other brand and product names are registered trademarks or trademarks of their respective companies.

Table of Contents
Acknowledgments ....................................................................................................vii
1

Introduction to Dates and Times in SAS ................................................ 1
1.1
1.2
1.3
1.4
1.5
1.6

2

How Does It Work? (January 1, 1960 and Midnight as Zero) .......................... 2
Internal Representation (Storage as Integers or Real Numbers).......................... 2
External Representation (Basic Format Concepts)............................................. 3
Date and Time as Numeric Constants in SAS.................................................. 3
System Options Related to Dates ................................................................... 5
Length and Numeric Requirements for Date, Time, and Datetime .................... 12

Displaying SAS Date, Time, and Datetime Values as Dates and Times
as We Know Them............................................................................. 15
2.1
2.2
2.3
2.4

How Do I Use a Format? ............................................................................ 16
So Just How Many Built-in Formats Are There for Dates and Times?................. 18
A Quick Note About Date Formats, Justification, and ODS............................. 19
Detailed Discussion of Each Format ............................................................. 19
2.4.1 Date Formats .................................................................................. 19
2.4.2 Time Formats .................................................................................. 43
2.4.3 Datetime Formats ............................................................................ 47
2.5 Creating Custom Date Formats Using the VALUE Statement of
PROC FORMAT ........................................................................................ 54
2.6 Creating Custom Date Formats Using the PICTURE Statement of
PROC FORMAT ........................................................................................ 56
2.7 The PUT( ) Function and Formats.................................................................. 60

iv Table of Contents

3

Converting Dates and Times into SAS Date, Time,
and Datetime Values.......................................................................... 63
3.1 Avoiding the Two-Digit Year Trap................................................................ 64
3.2 Using Informats ......................................................................................... 65
3.3 The INFORMAT Statement.......................................................................... 66
3.3.1 Using Informats with the INPUT Statement .......................................... 66
3.3.2 Informats with the INPUT( ) Function................................................... 67
3.3.3 When the Informat Does Not Match the Data Being Read.................... 68
3.4 Listing and Discussion of Informats .............................................................. 70
3.4.1 Date Informats ................................................................................ 70
3.4.2 Time Informats ................................................................................ 75
3.4.3 Datetime Informats .......................................................................... 77
3.4.4 ANYDT and Its Variants ................................................................... 77

4

Date and Time Functions .................................................................... 85
4.1
4.2
4.3
4.4

5

Current Date and Time Functions................................................................. 86
Extracting Pieces from SAS Date, Time, and Datetime Values ......................... 86
Creating Dates, Times, and Datetimes from Numbers .................................... 89
Calculating Intervals .................................................................................. 93
4.4.1 Calculating Elapsed Time with DATDIF( ) and YRDIF() .......................... 93
4.4.2 The Basics of SAS Intervals............................................................... 96
4.4.3 The Interval Calculation Functions: INTCK and INTNX ......................... 98

Deeper into Dates and Times with SAS ............................................. 107
5.1 Macro Variables and Dates...................................................................... 108
5.1.1 Automatic Macro Variables ............................................................ 108
5.1.2 Putting Dates into Titles .................................................................. 109
5.1.4 Using %SYSFUNC() to Create Dates, Times, and Datetimes in
Macro Variables ........................................................................... 110
5.1.4 Using CALL SYMPUT( ) and SYMGET() with Dates, Times, and
Datetimes ..................................................................................... 111
5.2 Shifting SAS Date and Time Intervals ......................................................... 113
5.3 Graphing Dates ...................................................................................... 122

Table of Contents v

5.4 The Basics of PROC EXPAND ................................................................... 127
5.4.1 Capabilities of PROC EXPAND ....................................................... 127
5.4.2 Using PROC EXPAND to Convert to a Higher Frequency ................... 129
5.4.3 Using PROC EXPAND to Convert to a Lower Frequency..................... 130
5.4.4 Using PROC EXPAND to Interpolate Missing Values .......................... 132
5.4.5 The OBSERVED= Option for the CONVERT Statement in
PROC EXPAND............................................................................. 133
5.5 International Date, Time, and Datetime Formats and Informats...................... 136
5.5.1 “EUR” Formats and Informats.......................................................... 137
5.5.2 “NL” Formats................................................................................ 140
5.5.3 Specific Language Date Formats and Informats................................. 143
5.6 Other Software and Their Dates (Excel, Oracle, DB2).................................. 144
Appendix A Quick Reference Guide to SAS Date, Time, and Datetime
Formats ................................................................................ 149
Index ..................................................................................................... 151

vi

Acknowledgments
Many people helped to make this book happen. I shouldn’t get all of the credit.
Firstly, I’d like to give special thanks to Patsy Poole and Julie Platt from SAS Press.
Their encouragement and enthusiasm kept me going. I owe a lot to Art Carpenter,
SAS guru. This book would not exist without his interest, patience, and gentle
direction. Another big thank you goes to Caroline Brickley, Joan Stout Knight,
Candy Farrell, and Patrice Cherry, all from SAS Press, who turned my manuscript into
a real book.
Thanks to Andrew Karp for introducing me to the world of PROC EXPAND, and to
Mike Forno at SAS Institute’s Technical Support for answering my questions on it. I
greatly
appreciate
the
American
Public
Transportation
Association
(http://www.apta.com,) who allowed me to use data that they compiled from their
member transit agencies for the PROC EXPAND examples, and Erik Tilanus for
sharing some of his knowledge to help improve the content of this book.
I’d also like to thank the technical reviewers from SAS Institute, Richard Bell, Chris
DeHart, Rick Langston, and Kim Wilson for their thoughtful comments and corrections,
as well as Michelle Schlude from SAS Institute’s Technical Support for helping to iron
out the more sticky points of intervals.
Closer to home, I want to acknowledge the Divisions of Biostatistics and Statistical
Genomics at Washington University, especially Drs. D.C. Rao and Michael Province
for their moral support, Jeanne Cashman for proofing the final draft, and Avril
Adelman for giving me a SAS user’s perspective.
Last, but most certainly not least, my wife Billie, and son Terec deserve a great deal of
thanks for letting me spend a good number of my evenings and weekends with
Microsoft Word and SAS instead of them.

viii

CHAPTER 1

Introduction to Dates and Times in SAS
1.1 How Does It Work? (January 1, 1960 and Midnight as Zero) ................................ 2
1.2 Internal Representation (Storage as Integers or Real Numbers)................................ 2
1.3 External Representation (Basic Format Concepts)................................................... 3
1.4 Date and Time as Numeric Constants in SAS........................................................ 3
1.5 System Options Related to Dates ......................................................................... 5
1.6 Length and Numeric Requirements for Date, Time, and Datetime...........................12

2

The Essential Guide to SAS Dates and Times

In the years that I’ve been working with SAS, and teaching students how to use it, I’ve noticed
two things about it that consistently confuse programmers who are new to SAS. First, there is
the “implied” DO-UNTIL (end-of-file) of the DATA step, and then there is the concept of dates
(and times) within SAS. I’ve seen many misuses of character strings masquerading as dates
and/or times over the past years. However, this is only the tip of the iceberg when it comes to
the power and flexibility of dates and times in SAS. There is much more than just having
numbers representing date and time values in SAS. We’ll start with the basics in the first three
chapters, and then progress to some more advanced uses of those date and time values.

1.1 How Does It Work? (January 1, 1960 and Midnight
as Zero)
SAS has three separate counters that keep track of dates and times. The date counter started
at zero on January 1, 1960. Any day before 1/1/1960 is a negative number, and any day
after that is a positive number. Every day at midnight, the date counter is increased by one.
The time counter runs from zero (at midnight) to 86,399.9999, when it resets to zero. The last
counter is the datetime counter. This is the number of seconds since midnight, January 1,
1960. Why January 1, 1960? One story has it that the founders of SAS wanted to use the
approximate birth date of the IBM 370 system, and they chose January 1, 1960 as an easyto-remember approximation.
Many database programs maintain their dates as a value relative to some fixed point in time.
This makes calculating durations easy, and working with dates stored in this fashion becomes
a matter of addition, subtraction, multiplication, and division.

1.2 Internal Representation (Storage as Integers or Real
Numbers)
SAS stores dates as integers, while the datetime and time counters are stored as real numbers
to account for fractional seconds. The origin of the algorithm used for SAS date processing
comes from a Computerworld article dated January 14, 1980 by Dr. Bhairav Joshi of SUNYGeneseo. The earliest date that SAS can handle with this algorithm is January 1, 1582. The
latest date is far enough into the future that four digits can’t display the year.

Chapter 1: Introduction to Dates and Times in SAS

3

1.3 External Representation (Basic Format Concepts)
The dates as stored by SAS don’t do us much good in the real world. The statement “I was
born on –242” won’t mean much to anyone else. On the other hand, “May 4, 1959” can
easily be translated into something that most people can understand. SAS has a built-in facility
to perform automatic translation between SAS numbers and dates and times as understood by
the rest of the world. This automatic translation is performed with what are called formats.
Formats display the date, time, and datetime values in a fashion that is much more easily
understood. Formats do not change the values themselves; they are just a way to display the
values in any output.
What happens if you have a date or time and want to translate it into SAS date and time
values? SAS has another built-in facility which performs the reverse translation, from the dates
and times we understand and use to the values that SAS stores. This translation is done using
informats. Informats translate what they are given into the values that are stored in SAS
variables. We will discuss formats and informats in detail in Chapters 2 and 3, because there
are dozens of them.

1.4 Date and Time as Numeric Constants in SAS
We’ve talked about internal and external representation of dates and times. How do you put a
specific date into a program as a constant? Formats change the way the values are displayed
in output, so you can’t use them. Informats translate what they are given, so you could use
them, but then you’d need to use the INPUT( ) function (see Section 3.3.2), which takes a
value you give it and translates it with an INFORMAT. That’s very inefficient. Look at the
following program (Example 1.4.1) to see how date, time, and datetime constants are written
into a SAS program. Take note of the quotation marks around the values for date, time, and
datetime, and the letters that follow each closing quote.
The quotes are used to create a literal value. You may use a pair of single or double quotes to
specify the literal value. The only difference between using single and double quotes around
the date would be macro expansion. The most important part of a date constant is the letter
that immediately follows the last quote. The letter “D” stands for date, “T” for time, and “DT”
for datetime, and you can use either upper or lowercase. If you put a date in quotes without
the letter at the end, you will create a character variable, not a numeric variable with a date,
time, or datetime value. The difference might not become apparent until you try to do
something with the variable you created that involves a calculation. Don’t forget your “D”, “T”,

4

The Essential Guide to SAS Dates and Times

or “DT”! Example 1.4.1 demonstrates how date constants are defined and then automatically
converted to SAS date values.
Example 1.4.1 Date Constants
DATA date_constants;
date = ‘04aug2004’d; /* This is a date constant */
time = ‘07:15:00’t;
/* This is a time constant */
datetime = ‘07aug1904:21:31:00’dt; /* This is a datetime constant */
run;
TITLE “Unformatted Constants”;
PROC PRINT DATA=date_constants;
VAR date time datetime;
run;
TITLE “Formatted Constants”;
PROC PRINT DATA=date_constants;
VAR date time datetime;
FORMAT date worddate32. time timeampm9. datetime datetime32.;
the constants */
run;

/* Format

Here is the resulting output:
Unformatted Constants
date

time

datetime

16287 26100 -1748226540

Formatted Constants
date

time

datetime

August 4, 2004 7:15 AM 07AUG1904:21:31:00

Without formats, you can see that the date constants we created are stored as their actual SAS
date, time, and datetime values. They don’t make much sense until you format them.

Chapter 1: Introduction to Dates and Times in SAS

5

1.5 System Options Related to Dates
SAS has several system options; these affect the way that the SAS job or session works. There
are four important options that affect dates: YEARCUTOFF, DATESTYLE, DATE/NODATE, and
DTRESET.

YEARCUTOFF
On December 31, 1999, people were holding their breath. The majority of dates stored on
computers allowed only two digits for the year, and assumed that the first two digits were (and
would always be) “19”. This didn’t account for storage of dates where the first two digits of
the year were not “19”, and thus, the “Y2K problem” was born. How does SAS handle twodigit years? When is a two-digit year in the 1900’s, and when is it in the 2000’s? What if
you have old data and all those dates need to be in the 1800’s? What does SAS do? The
answer is: YOU tell SAS how to handle two-digit years. There is a system option called
YEARCUTOFF that lets you specify a 100-year span for two-digit years. It applies to all dates
with two-digit years that you give SAS. This means that it applies to: date constants, date
values read from raw data with the INPUT statement, and date values that are created from
character strings with the INPUT( ) function. The YEARCUTOFF system option does not affect
values that are stored as SAS date values, regardless of their display, so once you create a
date or datetime value, YEARCUTOFF no longer has any effect on it.
The system default is 1920. This means that any two-digit year from 20 to 99 will be
translated as 1920 to 1999, while years from 00 to 19 will be translated as 2000 to 2019.
The syntax is:
OPTIONS YEARCUTOFF= (y)yyyy;

/* (y)yyyy can be from 1582 to 19900 */

Let’s use a series of OPTIONS statements and date constants to illustrate. In the following
program, three datasets are created with four identical date constants that use two-digit years.
The only thing that changes is the value of YEARCUTOFF. Example 1.5.1 shows how
YEARCUTOFF translates two-digit year values using date constants.

6

The Essential Guide to SAS Dates and Times

Example 1.5.1 How the YEARCUTOFF System Option Works
OPTIONS YEARCUTOFF=1920;

/* SAS System default */

DATA yearcutoff1;
date1 = “15JUL06”d;
date2 = “27FEB48”d;
date3 = “04may69”d;
date4 = “10dec95”d;
RUN;
PROC PRINT DATA=yearcutoff1;
FORMAT date1-date4 mmddyy10.;
RUN;

Here is the resulting output:
date1

date2

date3

date4

07/15/2006

02/27/1948

05/04/1969

12/10/1995

With the default of 1920 in effect, you can see that the first date is placed in the 21st century,
while the others remain in the 20th. Let’s move the 100-year period back by 80 years and see
what happens.
OPTIONS YEARCUTOFF=1840;
DATA yearcutoff2;
date1 = “15JUL06”d;
date2 = “27FEB48”d;
date3 = “04may69”d;
date4 = “10dec95”d;
RUN;
PROC PRINT DATA=yearcutoff2;
FORMAT date1-date4 mmddyy10.;
RUN;

Chapter 1: Introduction to Dates and Times in SAS

7

Here is the resulting output:
date1

date2

date3

date4

07/15/1906

02/27/1848

05/04/1869

12/10/1895

Now the first date is in the 20th century, and the others are in the 19th. Note that the only
change to the code is in the OPTIONS statement. The value of YEARCUTOFF is 1840 instead
of 1920. For the last part of this example, we’ll set YEARCUTOFF to 1970, and use the same
date constants with two-digit years again.
OPTIONS YEARCUTOFF=1970;
DATA yearcutoff3;
date1 = “15JUL06”d;
date2 = “27FEB48”d;
date3 = “04may69”d;
date4 = “10dec95”d;
RUN;
PROC PRINT DATA=yearcutoff3;
FORMAT date1-date4 mmddyy10.;
RUN;

Here is the resulting output:
date1

date2

date3

date4

07/15/2006

02/27/2048

05/04/2069

12/10/1995

Once again, the only difference in the code is in the OPTIONS statement. Now the 100-year
range starts in 1970, which places every date except the last one in the 21st century.
As with many SAS system options, YEARCUTOFF is effective when it is encountered within the
program. If you have multiple OPTIONS statements that include YEARCUTOFF= in your
program, each one will affect all date constants, raw data, and date values created from
character strings with the INPUT( ) function until the next OPTIONS YEARCUTOFF= statement
changes the 100-year range. As an example, if you were to put the three programs in the
above example together in one file, the result would be the same, as long as you did not move
the OPTIONS YEARCUTOFF= statements.

8

The Essential Guide to SAS Dates and Times

DATESTYLE
This system option is important if you are using any of the following informats: ANYDTDTE.,
ANYDTDTM., or ANYDTTME. DATESTYLE controls how SAS will translate dates that can be
interpreted in more than one way. This happens most often when you are using two-digit
years.
Assuming that the OPTIONS statement specifies YEARCUTOFF=1920, does 11-01-06 mean
November 1, 2006, January 6, 2011, or January 11, 2006?
DATESTYLE allows you to tell SAS how to interpret cases like this. You may specify any one of
the following:
Table 1.5.1 Values for DATESTYLE=

MDY

Sets the default order as month, day,
year. “11-01-06” would be translated
as November 1, 2006

YDM

Sets the default order as year, day,
month. “11-01-06” would be
translated as June 1, 2011

MYD

Sets the default order as month, year,
day. “11-01-06” would be translated
as November 6, 2001

DMY

Sets the default order as day, month,
year. “11-01-06” would be translated
as January 11, 2006

YMD

Sets the default order as year, month,
day. “11-01-06” would be translated
as January 6, 2011

DYM

Sets the default order as day, year,
month. “11-01-06” would be
translated as June 11, 2001

LOCALE
(default)

Sets the default value according to the LOCALE= system option. When the default value for the
LOCALE= system option is “English_US”, this sets DATESTYLE to MDY. Therefore, by default, “1101-06” would be translated as November 1, 2006.

DATESTYLE can be set at SAS invocation, through an OPTIONS statement, in the configuration
file, or in the SAS Options window. The syntax is:
OPTIONS DATESTYLE=order;

/* order is one of the values from table 1.1 */

Example 1.5.2 demonstrates the effect of the different DATESTYLE values on a given character
string.

Chapter 1: Introduction to Dates and Times in SAS

9

Example 1.5.2 How DATESTYLE Affects the ANYDTDTE. Informat
The following program goes through each of the possible values for DATESTYLE using the
same character string 11-01-06 as input. The log shown below the program will demonstrate
the differences.
OPTIONS DATESTYLE=mdy;
DATA _NULL_;
INPUT date anydtdte8.;
PUT “OPTIONS DATESTYLE=mdy, so date=“ date mmddyy10.;
DATALINES;
11-01-06
;
RUN;
OPTIONS DATESTYLE=myd;
DATA _NULL_;
INPUT date anydtdte8.;
PUT “OPTIONS DATESTYLE=myd, so date=“ date mmddyy10.;
DATALINES;
11-01-06
;
RUN;
OPTIONS DATESTYLE=ymd;
DATA _NULL_;
INPUT date anydtdte8.;
PUT “OPTIONS DATESTYLE=ymd, so date=“ date mmddyy10.;
DATALINES;
11-01-06
;
RUN;
OPTIONS DATESTYLE=ydm;
DATA _NULL_;
INPUT date anydtdte8.;
PUT “OPTIONS DATESTYLE=ydm, so date=“ date mmddyy10.;
DATALINES;
11-01-06
;
RUN;

10

The Essential Guide to SAS Dates and Times
OPTIONS DATESTYLE=dmy;
DATA _NULL_;
INPUT date anydtdte8.;
PUT “OPTIONS DATESTYLE=dmy, so date=“ date mmddyy10.;
DATALINES;
11-01-06
;
RUN;
OPTIONS DATESTYLE=dym;
DATA _NULL_;
INPUT date anydtdte8.;
PUT “OPTIONS DATESTYLE=dym, so date=“ date mmddyy10.;
DATALINES;
11-01-06
;
RUN;
OPTIONS DATESTYLE=locale; /* LOCALE=EN_US */
DATA _NULL_;
INPUT date anydtdte8.;
PUT “OPTIONS DATESTYLE=locale, so date=“ date mmddyy10.;
DATALINES;
11-01-06
;
RUN;

The Log
OPTIONS
OPTIONS
OPTIONS
OPTIONS
OPTIONS
OPTIONS
OPTIONS

DATESTYLE=mdy, so
DATESTYLE=myd, so
DATESTYLE=ymd, so
DATESTYLE=ydm, so
DATESTYLE=dmy, so
DATESTYLE=dym, so
DATESTYLE=locale,

date=11/01/2006
date=11/06/2001
date=01/06/2011
date=06/01/2011
date=01/11/2006
date=06/11/2001
so date=11/01/2006

As you can see, DATESTYLE can have an enormous effect when the ANYDTDTE. (or
ANYDTDTM. or ANYDTTM.) informats are used.

Chapter 1: Introduction to Dates and Times in SAS

11

DATE/NODATE
By default, the DATE system option is in effect when you start SAS, which causes the date and
time that the SAS job (or session) started to appear on each page of the SAS log and SAS
output. These values are obtained from the operating system clock. If you are running SAS
interactively, then the date and time are printed only on the output, not the log. If you don’t
want the date and time to appear, use the NODATE system option. The syntax is:
OPTIONS NODATE;
If you’ve turned off DATE, then you can turn it back on with:
OPTIONS DATE;
Example 1.5.3 shows what happens to the title line printed by SAS when you use DATE and
NODATE. Remember that, by default, DATE is in effect when you start SAS.
Example 1.5.3 DATE/NODATE
This is a sample of a title line with the DATE system option:
The SAS System

17:20 Thursday, August 5, 2004

1

This is what NODATE does to that title line:
The SAS System

1

DTRESET
If the DATE option is enabled, SAS prints the date and time that the current SAS session
started. If you want a more accurate date and time on those pages, you can use the DTRESET
system option. This will cause SAS to get the date and time from the operating system clock
each time a page is written. That date and time will then be put on the page instead of the
time that the SAS job started. Since the time is displayed in hours and minutes, you will see it
change each minute only. The syntax is:
OPTIONS DTRESET;

12

The Essential Guide to SAS Dates and Times

1.6 Length and Numeric Requirements for Date, Time,
and Datetime
Since dates are stored as integers, you can take advantage of that to save space when you
create variables to store them. Instead of using the default length of 8 for numeric variables,
set the LENGTH of the numeric variables where you are storing the dates to 4. This will safely
store dates from January 1, 1582 (the earliest date SAS can handle), to October 23, 7701. A
length of 5 is overkill, although that would extend the ending date another 534,773,760
days! A length of 3 will not accurately store dates outside the range of January 1, 1960 and
September 13, 1960. If you declare your date variables to be a length of 4, you will be able
to store two dates in the space it would take to store one if you were using the SAS default
length for numeric variables.
Times may present a little bit of a problem, since times have the possibility of having decimal
parts. You can get away with storing times in the same magic length of 4 that you can use for
dates, and the rule is simple enough: if you want fractional seconds in your time values, use a
length of 8 for maximum precision. Otherwise, the same length of 4 will store every possible
whole second from midnight to midnight.
Datetime values need to be a little longer; a length of 4 will not store a datetime value with
accuracy, regardless of whether you want decimal places. The number is just too big. Use a
length of 6 to store datetime values; this will accurately represent datetime values (without
fractions of seconds) from midnight, January 1, 1582 to 3:04:31 PM on April 9, 6315. Note
that a length of 6 might not translate into other databases.
In all the above cases, the minimum lengths for accuracy have been given to you; do not
attempt to save more space by shrinking the variables further. You will lose precision, and this
could lead to unexpected results. Example 1.6.1 shows what can happen if you do not use
enough bytes to store your date values.
Example 1.6.1 The Effect of LENGTH Statements on Dates
DATA date_length;
LENGTH len3 3 len4 4 len5 5;
len3 = ‘05AUG2004’d+1;
len4 = ‘05AUG2004’d+1;
len5 = ‘05AUG2004’d+1;
FORMAT len3 len4 len5 mmddyy10.;
RUN;
PROC PRINT DATA=date_length;
RUN;

Chapter 1: Introduction to Dates and Times in SAS

13

Here is the resulting output. Notice that the date in len3 is different from the one in the other
two variables. This is what can happen when you shrink the size of the variable too much.
Instead of August 6, 2004, the value is wrong.
len3

len4

len5

08/05/2004 08/06/2004 08/06/2004

14

CHAPTER 2

Displaying SAS Date, Time, and
Datetime Values as Dates and Times as
We Know Them
2.1 How Do I Use a Format? ................................................................................... 16
2.2 So Just How Many Built-in Formats Are There for Dates and Times?........................ 18
2.3 A Quick Note About Date Formats, Justification, and ODS.................................... 19
2.4 Detailed Discussion of Each Format .................................................................... 19
2.4.1 Date Formats ......................................................................................... 19
2.4.2 Time Formats ......................................................................................... 43
2.4.3 Datetime Formats ................................................................................... 47
2.5 Creating Custom Date Formats Using the VALUE Statement of PROC FORMAT........ 54
2.6 Creating Custom Date Formats Using the PICTURE Statement of PROC FORMAT ..... 56
2.7 The PUT( ) Function and Formats......................................................................... 60

16

The Essential Guide to SAS Dates and Times

SAS date, time, and datetime values are stored as integers (unless you are storing fractional
parts of seconds). They are all counted from a fixed reference point. SAS date values
increment by 1 at midnight of each day, while SAS datetime values increment by 1 every
second. SAS time values start at zero at midnight of each day, and increment by 1 each
second.
This scheme makes it easy to calculate durations in days and seconds, but it does not do much
for figuring out what a given SAS date, time, or datetime value means in terms of how we talk
about them. Therefore, SAS provides a facility that makes it easy to perform the translation
from SAS into the common terminology of months, days, years, hours, and seconds. The
translation is done through formats.
Formats are what SAS uses to control the way data values are displayed. They can also be
used to group data values together for analysis. They are essential to dates and times in SAS
because SAS does not store dates and times in an easily recognizable form, as we discussed
in Chapter 1. SAS has many built-in formats to display dates, times, and datetime values.
Here’s your handy guide to all of the date, time, and datetime formats readily available in
SAS. In addition, if any of these built-in formats don’t fit your needs, you have the ability to
create (and store for future use) your own formats, which is covered in Sections 2.5 and 2.6.
If you are looking for a quick reference, you can go to Appendix A, which lists all of the date,
time, and datetime formats, and gives a sample display using their default lengths. If the
default does not give you what you want, Section 2.4 discusses each date, time, and datetime
format in detail, including how to specify the length of the format, and how that length affects
the display.

2.1 How Do I Use a Format?
Formats are easy to use. You can permanently associate a format with a variable by using a
FORMAT statement in a DATA step as shown in Example 2.1.1.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

17

Example 2.1.1 Permanently Associating a Format with a Variable
DATA test;
LENGTH date1 time1 4;
date2 = 16048;
time2 = 733000;
FORMAT date1 MMDDYY10. time1. TIMEAMPM11.;
RUN;

This example will create a dataset called TEST, which has two variables, date1, and time1. By
using the FORMAT statement here, you have specified that whenever the values from this
dataset are displayed, the values stored in the variable date1 will always be displayed with
the format MMDDYY10., and those stored in time1 will always be displayed using the
TIMEAMPM11. format.
If you don’t want to have your data values permanently associated with a format, then you
can just apply the format when you are actually writing the values to your output. The same
FORMAT statement is used, but the location has changed, from the DATA step to the PROC
step. Example 2.1.2 illustrates this.
Example 2.1.2 Associating a Format with a Variable for the Duration
of a Procedure
DATA test2;
LENGTH date2 time2 4;
date2 = 16048;
time2 = 733000;
RUN;
PROC PRINT DATA=test2;
FORMAT date2 DATE9. time2 TIMEAMPM11.;
RUN;

Now, although there is no format assigned to either date2 or time2 in the DATA step, you
have told the PRINT procedure to write these values using the two formats listed. There’s
another handy thing about using the FORMAT statement with a SAS procedure: if you use the
FORMAT statement in a SAS procedure, it will override any format that has been permanently
associated with the variables for the duration of that procedure. To illustrate, we’ll take the
dataset “test” from Example 2.1.2 above. The variables date1 and time1 have been
associated with the formats MMDDYY10. and TIMEAMPM11., respectively. What if your

18

The Essential Guide to SAS Dates and Times

report needs the date printed out with the day of the week, month name, day, and year, while
the time needs to be seconds after midnight? The PROC PRINT step will look like this:
PROC PRINT DATA=test;
FORMAT date1 WEEKDATE37. time1;
RUN;

All SAS procedures will use the formats specified in the FORMAT statement that is part of the
PROC step instead of the formats associated with the variable in the dataset. Therefore, in the
above example, date1 will be printed with the WEEKDATE. format. What about time1?
There’s no format name given after the variable name in the FORMAT statement. This is how
to tell SAS not to use any formats that may be associated with the variable. To remove a
FORMAT from a variable, make sure that no format names of any kind follow it anywhere in
the FORMAT statement. In the following code segment, both time1 and date1 will be
formatted with WEEKDATE37.
PROC PRINT DATA=test;
FORMAT time1 date1 WEEKDATE37.;
RUN;

2.2 So Just How Many Built-in Formats Are There for
Dates and Times?
The answer is lots. We will discuss each of them in detail here, but if you’re looking for a
quick reference, see Appendix A. SAS formats have their own syntax structure. There is a
format name, followed by a width specification, and they all end with a period. The period is
critical – it is what allows SAS to recognize the word as a format, and not some other SAS
keyword, or text. The width specification varies with each format. This is very important to
dates, because SAS will make abbreviations to the displayed value if you do not specify
enough characters for the width specification. The abbreviation that SAS will use may not give
you the output that you want. Each format has its own default width, which is what SAS will
use if you do not specify a width. The default width is noted in the description for each format
below, and it is usually the width that will accommodate the longest value to be displayed. For
example, the default width for the DOWNAME. format is 9. That will accommodate the string
Wednesday, which is the longest English day-of-week name.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

19

2.3 A Quick Note About Date Formats, Justification, and
ODS
Each date format has a default justification with respect to the width specification that you give
it. Since numeric values are right-justified in SAS, most formats that are applied to date, time
or datetime formats are right-justified, with a few exceptions. This is only applicable to
traditional column-based output. In ODS destinations other than LISTING, values are justified
within a table column by the SAS procedure default or by a user-defined ODS template. By
default, SAS makes its columns wide enough to fit the widest item in a given column.
Therefore, any leading spaces caused by specifying a width that is too wide to fit the
formatted value won’t show up in ODS output.
If you do not specify column alignment in an ODS template, certain ODS destinations (such as
RTF and PDF) will justify values within a column according to the justification of the format
used in the column, without leading spaces.

2.4 Detailed Discussion of Each Format
This section will give a detailed explanation of all the current standard formats available for
SAS date, time, and datetime values. In addition to the display that results from using a given
format, the explanation includes information on the default width specification and its possible
values, annotated examples of the display with varying width specifications, and usage notes.
Date formats will be covered first, then time and datetime formats. Each subsection is
arranged alphabetically.

2.4.1 Date Formats
A date format translates SAS date values into one of several easily recognized equivalents.
You may specify the width (number of characters) that the translated text will occupy, but each
format has its own default width specification, shown as w in this text. The default width
specification is given in the description of each format. Some, but not all, of the date formats
allow you to specify the character that separates each element of the date. You must not use a
date format to translate datetime values. If you try to translate a datetime value with a date
format, you will get incorrect output. (For an example, see Section 2.4.3.)

20

The Essential Guide to SAS Dates and Times

DATEw. Writes dates as the numerical day of the month followed by the three-letter month
abbreviation and the year, without any separating characters. It is right-justified within the
field. w can be from 5–9, and the default width is 7. If you want to display four-digit years,
use DATE9. The following table shows the result when the date value is 8449, which
corresponds to February 18, 1983. Note the alignment of the date printed.

Format Name

Result

DATE.

18FEB83

DATE5.

18FEB

Comment

No room for year to be displayed.

DATE6.

18FEB

DATE7.

18FEB83

DATE8.

18FEB83

DATE9.

18FEB1983

Output is moved to the right by 1 space.

Two-digit year, leading space.

This format is analogous to the DTDATE. format, which displays datetime values in the same
manner.
DAYw. Writes the numerical day of the month, and it is right-justified within the field. w can
be from 2–32, and the default width is 2. Specifying anything longer than 2 will only place
more spaces in the field to the left of the number, so it’s not necessary to specify more than 2.
The following table shows the result when the date value is 16739, which corresponds to
October 30, 2005:

Format Name

Result

DATE2.

30

DATE5.

30

Comment

See how the day is moved three spaces to the right.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

21

DDMMYYw. Writes dates as day/numerical month/year, where the slash (/) is the
separator, and it is right justified within the field. w can be from 2–10, and the default width
is 8. If you specify a width from 2–5, the date will be truncated on the right, with SAS trying to
fit as much of the day and month as possible in the space allowed. If you use 6, no slashes
will be printed. A width of 7 will cause SAS to print a two-digit year without a slash, and
widths of 8 or 9 will put a two-digit year after the slashes. Use 10 to get a four-digit year with
slashes. The following table shows the result when the date value is 15486, which
corresponds to May 26, 2002:

Format Name

Result

DDMMYY5.

26/05

DDMMYY6.

260502

DDMMYY7.

260502

DDMMYY8.

26/05/02

DDMMYY9.
DDMMYY10.

26/05/02

Comment

Moved right 1 space.

Still a two-digit year, moved right 1 space.

26/05/2002

DDMMYYxw. Is similar to DDMMYYw., above. It is also right-justified. However, with this
format, you can specify what character separates the day, numerical month, and year. The x
in the format name represents the separator between the day, month, and year. x can be:

x

Character Displayed in Output

B

blank

C

colon (:)

D

dash (—)

N

no separator

P

period (.)

S

slash (/)

Comment

w is a maximum of 8, not 10.

Effectively the same as using the DDMMYYw.
format.

22

The Essential Guide to SAS Dates and Times

w can be from 2–10, with the default being 8. This works the same way as the DDMMYY.
format with respect to what SAS fits in the space specified. Again, if you specify a width from
2–5, the date will be truncated on the right, with SAS trying to fit as much of the day and
month as possible in the space allowed. If you use 6, no separator will be used. At 7, SAS
will print a two-digit year without separator, and 8 or 9 will put a two-digit year after the
separator. Use 10 to get a four-digit year with your separator. The following table shows the
result when the date value is 16110, which corresponds to February 9, 2004:

Format Name Result

Comment

DDMMYYP5.

09.02

Only space for day and month

DDMMYYB6.

090204

Not enough space for the blank separator.

DDMMYYN7.

090204

DDMMYYD8.

09-02-04

DDMMYYS9.
DDMMYYC10.

09/02/04

No separator.
Enough space for two-digit year.
Enough space for two-digit year, same as using DDMMYY9.
format.

09:02:2004

DOWNAMEw. Writes the date as the name of the day of the week. It is right-justified, so if
you give it too much space, there will be leading blanks. w can be from 1 to 32, and the
default is 9. If you don’t specify w, SAS will print the entire name of the day. On the other
hand, if you don’t have enough space, SAS will truncate the name of the day to fit. The
following table shows the result when the date value is 17361, which corresponds to
Saturday, July 14, 2007:

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

Format Name

Result

DOWNAME5.

Satur

DOWNAME6.

Saturd

DOWNAME7.

Saturda

DOWNAME8.

Saturday

DOWNAME9.
DOWNAME10.
DOWNAME11.

23

Comment

“Saturday” is only 8 characters long, so 1 leading blank is added,
making it appear as if it has been moved to the right.

Saturday
Saturday

2 leading blanks added.

Saturday

3 leading blanks added.

JULDAYw. Writes the date as the Julian day of the year, which is a value from 1 to
366. It is right-justified. w can be from 3 to 32, and the default is 3.
Format Name

Result Comment

JULDAY3.

91

There is a leading space here because there are fewer than 3 digits in
the value displayed. The date value used here is 17988, which
corresponds to April 1, 2009.

JULDAY3.

107

There is no leading space here because there are 3 digits in the value
displayed. The date value used here is 18004, which corresponds to
April 17, 2009.

JULDAY4.

JULDAY.

91

91

2 leading spaces. You will also have 2 leading spaces there are fewer
than 2 digits and you specify w as 3. The date value used here is
17988, which corresponds to April 1, 2009.
Leading space. Default is 3. The date value used here is 17988, which
corresponds to April 1, 2009.

24

The Essential Guide to SAS Dates and Times

JULIANw. Writes your date value as a Julian date, with the year preceding the Julian day. It is rightjustified. w can be from 5 to 7, and the default is 5. If you specify a width of 5, the year portion of the
Julian date is two digits long, while specifying 6 will give you one leading blank and a two-digit year. If
you specify a width of 7, the year portion is four digits long. The following table shows the result when
the date value is 18004, which corresponds to April 17, 2009:

Format Name Result Comment
JULIAN5.

09107

JULIAN6.

09107

JULIAN7.

2009107

One leading blank added.

MMDDYYw. Writes the date as numerical month/day/year, where a slash (/) is the
separator. It is right-justified within the field. w can be from 2 to 10, and the default is 8. It is
similar to the DDMMYY. format in that if you specify 2–5 for the width, the date will be
truncated on the right, with SAS trying to fit as much of the day and month as possible in the
space allowed. If you use 6, no slashes will be printed, but it will print a two-digit year. At 7,
SAS will print a two-digit year without a slash, and 8 or 9 will put a two-digit year after the
slashes. Use a width of 10 to get a four-digit year with slashes. The following table shows the
result when the date value is 16773, which corresponds to December 3, 2005:

Format Name Result
MMDDYY2.

12

Comment
Month only.

MMDDYY3.

12

Month, with 1 leading space.

MMDDYY4.

1203

Month and day, no separator.

MMDDYY5.

12/03

Month and day with separating slash.

MMDDYY6.

120305

Month, day, and year, no separator.

MMDDYY7.

120305

MMDDYY8.

12/03/05

MMDDYY9.
MMDDYY10.

12/03/05
12/03/2005

Month, day, and year, no separator, leading blank.

Still a two-digit year, leading blank added.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

25

MMDDYYxw. Displays the date in the same way that the MMDDYY. format does, except
that you can specify the separator. The x in the format name specifies the separator that you
want to use according to the following table:

x

Character Displayed in Output

B

blank

C

colon (:)

D

dash (—)

N

no separator

P

period (.)

S

slash (/)

Comment

w is a maximum of 8, not 10.

Effectively the same as using the MMDDYYw.
format.

The date will be right-justified within the width you specify. w can be from 2 to 10, and the
default is 8. If you specify 2–5, the date will be truncated on the right, with SAS trying to fit as
much of the day and month as possible in the space allowed. If you use a width of 6, no
separator will be used. At 7, SAS will print a two-digit year without a separator, and widths of
8 or 9 will put a two-digit year after the separator. Use 10 to get a four-digit year with
separators. The following table shows the result when the date value is 15997, which
corresponds to October 19, 2003:

Format Name

Result

Comment

MMDDYYD5.

10-19

No room for year.

MMDDYYS6.

101903

No room for separators.

MMDDYYN7.

101903

MMDDYYC8.

10:19:03

MMDDYYP9.
MMDDYYB10.

10.19.03
10 19 2003

Leading space, no separator specified, not enough room for four-digit
year.
Colon as separator, still two-digit year.
Not enough room for four-digit year, leading space added.

26

The Essential Guide to SAS Dates and Times

MMYYw. Displays the zero-filled month number and year for the given date value,
separated by the letter M. It is right-justified, and w can be from 5 to 32, with a default width
of 7. When w is specified as 5 or 6, a two-digit year is used. If w is 7 or more, a full fourdigit year is displayed. Since this format can only display a maximum of 7 characters, a width
greater than 7 will just add leading spaces. The following table shows the result when the date
value is 16834, which corresponds to February 2, 2006:

Format Name Result
MMYY5.

02M06

MMYY6.

02M06

MMYY7.

02M2006

MMYY8.
MMYY9.

Comment

02M2006
02M2006

Two-digit year, leading space.
Four-digit year.
Four-digit year, 1 leading space.
Four-digit year, 2 leading spaces.

MMYYxw. Displays the month number and year for a given date value in the same fashion
as the MMYY format, except that you may specify the separator with x, according to the table
below. Note that the blank is not valid with this format, while it is valid with the
DDMMYYxw. and MMDDYYxw. formats.

x

Character Displayed in Output

C

colon (:)

D

dash (—)

N

no separator

P

period (.)

S

slash (/)

Comment

w can be from 4–32, with a default of 6.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

27

It is right-justified, and w can be from 5 to 32, with a default width of 7. When w is specified
as 5 or 6, a two-digit year is used. If w is 7 or more, a full four-digit year is displayed.
Specifying no separator with N will change the range of w from 4 to 32, and the default is
changed to 6. Since this format can only display a maximum of 7 characters, anything more
than 7 will just add leading spaces. The following table shows the result when the date value
is 15975, which corresponds to September 27, 2003:

Format Name Result

Comment

MMYYN5.

0903

1 leading space, no separator, two-digit year.

MMYYS6.

09/03

1 leading space, two-digit year.

MMYYD7.

09-2003

MMYYC8.
MMYYP9.

09:2003
09.2003

Four-digit year.
Four-digit year, 1 leading space.
Four-digit year, 2 leading spaces.

MONNAMEw. Displays the name of the month. It is right-justified, and w can be from 1 to
32, with a default of 9. Using a value greater than 9 will only add leading spaces. SAS will
truncate the month name as necessary to fit in the width. The following table shows the result
when the date value is 16338, which corresponds to September 24, 2004:

Format Name

Result

Comment

MONNAME3.

Sep

Specifying a w of 3 will display the 3-letter month abbreviation.

MONNAME4.

Sept

MONNAME5.

Septe

MONNAME6.

Septem

MONNAME7.

Septemb

MONNAME8.

Septembe

MONNAME9.

September

MONNAME10.

September

Leading space.

28

The Essential Guide to SAS Dates and Times

MONTHw. Displays the number of the month of the year. It is right-justified, and w can be
from 1 to 21, with a default of 2. Using a w of 1 will display the month number as a
hexadecimal value (1 through C). The following table shows the result when the date value is
16773, which corresponds to December 3, 2005:

Format Name Result
MONTH1.

C

MONTH2.

12

MONTH3.
MONTH4.

Comment
w of 1 always prints a single hexadecimal digit.

12
12

1 leading space.
2 leading spaces.

MONYYw. Displays the three-letter month abbreviation, followed by the year without any
separating characters. It is right-justified, and w can be from 5 to 7, with a default of 5.
Specifying a width of 5 will give you a two-digit year. A width of 6 will give you a two-digit
year and one leading space in the displayed date, while 7 will give you a four-digit year. It is
analogous to the DTMONYY format, which is used with datetime values. The following table
shows the result when the date value is 15323, which corresponds to December 14, 2001:

Format Name Result
MONYY5.

Comment

DEC01

MONYY6.

DEC01

MONYY7.

DEC2001

Two-digit year, 1 leading space.

PDJULGw. Writes a packed Julian date in hexadecimal format for IBM computers.
Justification is not an issue, and w can range from 3 to 16. The default width is 4. The Julian
date is written as follows: the four-digit Gregorian year is written in the first two bytes, and
the three-digit integer that represents the day of the year is in the next one-and-a-half bytes.
The last half-byte contains all binary 1’s, which indicates the value is positive.
If the SAS date value being translated by this format is a date constant with a two-digit year, it
will be affected by the YEARCUTOFF option. Look at the following SAS log.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

29

The Log
OPTIONS YEARCUTOFF=1880;
data _null_;
date1 = “15JUN2004”d;
date2 = “15JUN04”d; /* Affected by YEARCUTOFF option */
juldate1 = PUT(date1,pdjulg4.);
juldate2 = PUT(date2,pdjulg4.);
PUT juldate1= $hex8.;
PUT juldate2= $hex8.;
run;
juldate1=2004167F
juldate2=1904167F

PDJULIw. Writes a packed Julian date in hexadecimal format for IBM computers. It only
differs from the PDJULG. format in that it writes the century in the first byte as a two-digit
integer, followed by two digits of the year in the second byte. The next one-and-a-half-bytes
store the three-digit integer that corresponds to the day of the year, while the last half byte is
filled with hexadecimal 1’s that indicate a positive number. As with the PDJULG. format,
justification is not an issue, and the default width is 4, with a width range of 3 to 16.
The century and year are calculated by subtracting 1900 from the four-digit Gregorian year.
A year value of 1980 gives a century/year value of 0080 (1980-1900=80), while 2015
gives 0115 (2015-1900=115). Be aware that this format will not produce correct results for
years preceding 1900. The example below demonstrates.
OPTIONS YEARCUTOFF=2000;
DATA _NULL_;
date1 = “15JUN1804”d;
date2 = “15JUN1996”d;
date3 = “15JUN96”d;
juldate1 = PUT(date1,pdjuli4.);
juldate2 = PUT(date2,pdjuli4.);
juldate3 = PUT(date3,pdjuli4.);
PUT juldate1= $hex8.;
PUT juldate2= $hex8.;
PUT juldate3= $hex8.;
should_be_date1 = INPUT(juldate1,pdjuli4.);

30

The Essential Guide to SAS Dates and Times
PUT should_be_date1= mmddyy10.;
PUT should_be_date1= ;
RUN;

Here is the resulting output:
juldate1=009609DF
juldate2=0096167F
juldate3=0196167F
should_be_date1=04/12/1996
should_be_date1=13251

Date1 is in 1804, causing the PDJULI. representation of date1 (juldate1) to be incorrect.
While it should be the same day of the year (167) as date2 and date3, you can see that the
day is incorrectly written as 09D, while the century value is also incorrect, marked as 00
when, by the algorithm, it should be expressed as a negative number. This is verified by using
the PDJULI. informat to read juldate1, which gives a result of April 12, 1996, when it should
be June 15, 1804. (This is because there is no sign bit for julday1 to indicate that the value
should be negative.) The difference between date2 and date3 is caused by the YEARCUTOFF
option. The two-digit year 96 is translated as 2096, not 1996 because of the option.
QTRw. Writes a date value as the quarter of the year. It is right-justified, and w can range
from 1 to 32, with a default of 1. Since this format will only write 1 character, specifying a
width greater than 1 will just add leading spaces. The following table shows the result when
the date value is 12785, which corresponds to January 2, 1995:

Format Name Result
QTR1.
QTR3.
QTR6.

Comment

1
1

Two leading spaces.
1

Five leading spaces.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

31

QTRRw. Also writes a date value as the quarter of the year, except that it displays the
quarter as a Roman numeral. It is right-justified, and w can range from 3 to 32, with a default
of 3. This format will write a maximum of 3 characters. A width specification greater than 3
will add leading spaces, as shown here:

Format
Name Result
QTRR3.

III

QTRR3.

IV

Comment
The date value used is 14139 (September 16, 1998.)
With a date value of 14229 (December 16, 1998), there is 1 leading space.

WEEKDATEw. Writes date values as day-of-week name, month name, day, and year. It is
right-justified, and w can range from 3 to 37. The default is 29, which is the maximum width
of a date in this format. Specifying anything longer than 29 will cause leading spaces to be
added. If the width specified is too small to display the complete day of the year and month,
SAS will abbreviate. The following table shows the result when the date value is 15972,
which corresponds to September 24, 2003:

Format
Name

Result

WEEKDATE3. Wed
WEEKDATE5.

Wed

Comment
Three letter day-of-week abbreviation.
Two leading spaces.

WEEKDATE9. Wednesday

Will fit all day of week names. Leading spaces will
be added for days other than “Wednesday”.

WEEKDATE17. Wed, Sep 24, 2003

Full date information, abbreviated.

WEEKDATE20.

Wed, Sep 24, 2003

WEEKDATE23. Wednesday, Sep 24, 2003

Three leading spaces, date abbreviated.
Full day-of-week name, month name abbreviated.

WEEKDATE29. Wednesday, September 24, 2003
WEEKDATE30. Wednesday, September 24, 2003

Leading space.

32

The Essential Guide to SAS Dates and Times

WEEKDATXw. Writes date values as day-of-week name, day, month name, and year. It
differs from the WEEKDATE. format in that the day of the month precedes the month name. It
is right-justified, and w can range from 3 to 37. The default is 29, which is the maximum
width of a date in this format. Specifying anything longer than 29 will cause leading spaces to
be added. If the width specified is too small to display the complete day of the year and
month, SAS will abbreviate. The following table shows the result when the date value is
15972, which corresponds to September 24, 2003:

Format
Name

Result

Comment

WEEKDATX3.

Wed

Three letter day-of-week abbreviation.

WEEKDATX5.

Wed

Two leading spaces.

WEEKDATX9.

Wednesday

Will fit all day of week names. Leading spaces
will be added for days other than “Wednesday”.

WEEKDATX17.

Wed, 24 Sep, 2003

Full date information, abbreviated.

WEEKDATX20.

Wed, 24 Sep, 2003

WEEKDATX23.

Wednesday, 24 Sep, 2003

WEEKDATX29.

Wednesday, 24 September, 2003

WEEKDATX30.

Wednesday, 24 September, 2003

Three leading spaces, date abbreviated.
Full day-of-week name, month name abbreviated.

Leading space.

WEEKDAYw. Writes the date value as the number of the day of the week, where
1=Sunday; 2=Monday, etc.). It is right-justified, and w can be from 1 to 32. The default is 1.
Since the maximum width of the display is always one character, specifying anything more
will just cause leading spaces to be added. The following table shows the result when the date
value is 12533, which corresponds to Monday, April 25, 1994:

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

33

Format Name Result Comment
2

WEEKDAY1.

2

WEEKDAY2.

2

WEEKDAY3.

One leading space.
Two leading spaces.

WEEKUw. Writes the date value as a week number in decimal format using the U algorithm.
Unlike many other date, time, and datetime formats, it is left-justified. w can be from 1 to
200, and the default is 11. Specifying any value greater than 11 will display the same results
as if w were 11. The U algorithm calculates weeks based on Sunday being the first day of the
week, and the week number is displayed as a two-digit number from 0 to 53, with a leading
zero if necessary. The display that this format presents varies, based on the width
specification. The following table shows the result when the date value is 17232, which
corresponds to March 7, 2007, which was a Wednesday in the ninth week of the year:

Format
Name

Result

Comment

WEEKU3.

W09

“W” indicates week, week number follows, leading zero if necessary.

WEEKU4.

W09

Same as WEEKU3. No leading spaces.

WEEKU5.

07W09

Two-digit year precedes week.

WEEKU6.

07W09

Same as WEEKU5.

WEEKU7.

07W0904

Two-digit year precedes week, week followed by the number of the day of
the week.

WEEKU8.

07W0904

Same as WEEKU7.

WEEKU9.

2007W0904

Four-digit year precedes week, week number is followed by number of
the day of the week.

WEEKU10.

2007W0904

Same as WEEKU9.

WEEKU11.

2007-W09-04

Separator added between year, week number, and number of the day
of the week.

WEEKU12.

2007-W09-04

Same as WEEKU11.

34

The Essential Guide to SAS Dates and Times

WEEKVw. Writes the date value as a week number in decimal format using the V algorithm,
which is International Standards Organization (ISO) compliant. It is left-justified in the same
fashion as the WEEKU. format. w can be from 1 to 200, and the default is 11. Specifying
any value greater than 11 will display the same results as if w were 11. The V algorithm
calculates weeks based on Monday being the first day of the week, and the week number is
displayed as a two-digit number from 0 to 53, with a leading zero if necessary. In addition,
the first week of the year contains both January 4 and the first Thursday of the year. Therefore,
if the first Monday of the year falls on January 2, 3, or 4, the preceding days of the calendar
year are considered a part of week 53 of the previous calendar year. The following table
shows the result when the date value is 15340, which corresponds to December 31, 2001.
Note that although the date is in 2001, the algorithm used by this format places the date in
the year 2002. Monday, December 31, 2001, is considered to be the first day of the first
week of the year 2002.

Format
Name Result

Comment

WEEKV3.

W01

“W” indicates week, week number follows, leading zero if necessary.

WEEKV4.

W01

Same as WEEKV3. No leading spaces.

WEEKV5.

02W01

Two-digit year precedes week.

WEEKV6.

02W01

Same as WEEKV5.

WEEKV7.

02W0101

Two-digit year precedes week, week followed by the number of the day of
the week.

WEEKV8.

02W0101

Same as WEEKV7.

WEEKV9.

2002W0101

Four-digit year precedes week, week number is followed by number of
the day of the week.

WEEKV10. 2002W0101

Same as WEEKV9.

WEEKV11. 2002-W01-01

Separator added between year, week number, and number of the day of
the week.

WEEKV12. 2002-W01-01

Same as WEEKV11.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

35

WEEKWw. Writes the date value as a week number in decimal format using the W
algorithm. As with the WEEKU. and WEEKV. formats, it is left-justified. w can be from 1 to
200, and the default is 11. Specifying any value greater than 11 will display the same results
as if w were 11. The W algorithm calculates weeks based on Monday being the first day of
the week without any other restriction. The week number is displayed as a two-digit number
from 0 to 53, with a leading zero if necessary. The display that this format presents varies,
based on the width specification. The following table shows the result when the date value is
15340, which corresponds to December 31, 2001, (the same date used in the V algorithm
example above). Note that the W algorithm assigns the date as the first day of the last week
of the calendar year 2001.

Format
Name Result

Comment

WEEKW3. W53

“W” indicates week, week number follows, leading zero if necessary.

WEEKW4. W53

Same as WEEKW3. No leading spaces.

WEEKW5. 01W53

Two-digit year precedes week.

WEEKW6. 01W53

Same as WEEKW5.

WEEKW7. 01W5301

Two-digit year precedes week, week followed by number of day of week.

WEEKW8. 01W5301

Same as WEEKW7.

WEEKW9. 2001W5301

Four-digit year precedes week, week number is followed by number of the
day of the week.

WEEKW10. 2001W5301

Same as WEEKW9.

WEEKW11. 2001-W53-01

Separator added between year, week number, and number of the day of
the week.

WEEKW12. 2001-W53-01

Same as WEEKW11.

WORDDATEw. Displays the date value as name-of-month, day, and year. It is right-justified,
and w can range from 3 to 32. The default is 18. If the width specified is less than 18, SAS
will abbreviate and add leading spaces as necessary, regardless of whether the specific date
to be displayed will fit in the allocated space because of its value. The following table shows
the result when the date value is 15945, which corresponds to August 28, 2003:

36

The Essential Guide to SAS Dates and Times

Format
Name

Result

Comment

WORDDATE3. Aug
WORDDATE12. Aug 28, 2003
WORDDATE15.

Aug 28, 2003

Three leading spaces.

WORDDATE18.

August 28, 2003

Full month-name, but only 15 characters, therefore, 3 leading
spaces.

August 28, 2003

WORDDATE20.

Five leading spaces.

WORDDATXw. Displays the date value as day, name-of-month, and year. It differs from the
WORDDATE. format in that the day precedes the name-of-month. It is right-justified, and w
can range from 3 to 32. The default is 18. If the width specified is less than 18, SAS will
abbreviate and add leading spaces as necessary, even if the date to be displayed will fit in
the width specified. In the following table, you see that March is abbreviated for width
specifications less than 18, even though there is room to print the entire date string. The table
shows the result when the date value is 16144, which corresponds to March 14, 2004:

Format
Name
WORDDATX3.
WORDDATX12.
WORDDATX14.

Result

Comment

Mar
14 Mar 2004
14 Mar 2004

Leading space.
w is less than 18, so the format uses the abbreviated month
name, and adds leading spaces even though the text displayed
would fit in 13 characters.

WORDDATX16.

14 Mar 2004

w is still less than 18, so “March” is still abbreviated, and
more leading spaces are added.

WORDDATX18.

14 March 2004

Printed with leading spaces because date string is only 13
characters long.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

37

YEARw. Displays the year for the given date value. It is right-justified, and w can be from 2
to 4, with a default width of 4. When w is specified as 2 or 3, a two-digit year is used. The
following table shows the result when the date value is 18599, which corresponds to
December 3, 2010:

Format Name Result Comment
YEAR2.

10

YEAR3.

10

YEAR4.

2010

Two-digit year.
Two-digit year with a leading space.
Four-digit year.

YYMMw. Displays the year and month number for the given date value, separated by the
letter M. It is right-justified, and w can be from 5 to 32, with a default width of 7. When w is
specified as 5 or 6, a two-digit year is used. If w is 7 or more, a full four-digit year is
displayed. Since this format can only display a maximum of 7 characters, anything more than
7 will just add leading spaces. The following table shows the result when the date value is
14476, which corresponds to August 20, 1999:

Format Name Result
YYMM5.

99M08

Comment
Two-digit year.

YYMM6.

99M08

Leading space.

YYMM7.

1999M08

Four-digit year.

YYMM8.

1999M08

Leading space.

YYMMxw. Displays the year and month number for a given date value in the same manner
as the YYMM. format above, except that you may specify the separator with x according to
the table shown here. Unlike the DDMMYYxw., MMDDYYxw., and the YYMMDDxw.
formats, a blank is not a valid separator with this format.

38

The Essential Guide to SAS Dates and Times

x

Character Displayed in Output

C

colon (:)

D

dash (—)

N

no separator

P

period (.)

S

slash (/)

Comment

w can be from 4-–32, with a default of 6.

It is right-justified, and w can be from 5 to 32, with a default width of 7. When w is specified
as 5 or 6, a two-digit year is used. If w is 7 or more, a full four-digit year is displayed.
Specifying no separator with “N” will change the range of w from 4 to 32, and the default
width becomes 6. Since this format can only display a maximum of 7 characters, anything
more than 7 will just add leading spaces. The following table shows the result when the date
value is 16315, which corresponds to September 1, 2004:

Format Name Result
YYMMN4.

0409

YYMMC5.

04:09

YYMMD6.

04-09

YYMMP7.

2004.09

YYMMS8.

2004/09

Comment
No separator, minimum width is 4, two-digit year.

One leading space, two-digit year.
Four-digit year.
Four-digit year, 1 leading space.

YYMMDDw. This format is a variation on the DDMMYY. and MMDDYY. formats. It writes
the date as year-numerical month, where a dash (–) is the separator. It is right-justified within
the field. w can be from 2 to 10, and the default is 8. It is similar to the MMDDYY. format in
that if you specify the width from 2–5, the date will be truncated on the right, with SAS trying
to fit as much of the year and month as possible in the space allowed. If you use 6, no dashes
will be printed. At 7, SAS will print a two-digit year without a dash, and 8 or 9 will put a twodigit year before the first dash. Use a width of 10 to get a four-digit year with dashes. The
following table shows the result when the date value is 14927, which corresponds to
November 13, 2000:

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

Format
Name

Result

Comment

YYMMDD4. 0011

Two-digit year, month, not enough space for day.

YYMMDD5. 00-11

Two-digit year, month, dash separator, not enough space for
day.

YYMMDD6. 001113

Two-digit year, month, day, no separators.

YYMMDD7.

001113

YYMMDD8. 00-11-13
YYMMDD9.

00-11-13

YYMMDD10. 2000-11-13

39

One leading space, no separators.
Two-digit year
Two-digit year, leading space.
Four-digit year.

YYMMDDxw. Displays the date in the same way that the YYMMDD. format does, except
that you can specify the separator. The x in the format name specifies the separator that you
want to use according to the table shown here:

x

Character Displayed in Output

Comment

B

blank

C

colon (:)

D

dash (—)

Effectively the same as using the YYMMDDw. format.

N

no separator

w is a maximum of 8, not 10.

P

period (-)

S

slash (/)

The date will be right-justified within the width you specify. w can be from 2 to 10, and the
default is 8. If you specify 2–5, the date will be truncated on the right, with SAS trying to fit as
much of the day and month as possible in the space allowed. If you use 6, no separator will
be used. At 7, SAS will print a two-digit year without a separator, and 8 or 9 will put a two-

40

The Essential Guide to SAS Dates and Times

digit year before the first separator. The following table shows the result when the date value
is 17136, which corresponds to December 1, 2006:

Format
Name

Result

Comment

YYMMDDN4. 0612

Two-digit year, month, not enough space for day.

YYMMDDC5. 06:12

Two-digit year, month, colon separator, not enough space for day.

YYMMDDD6. 061201

Two-digit year, month, day, no separators.

YYMMDDP7.

061201

YYMMDDB8.

06 12 01

One leading space, no separators.
Two-digit year.

YYMMDDN8. 20061201
YYMMDDS9.

Because there is no separator, a four-digit year is displayed.

06/12/01

Two-digit year, leading space, slash separators.

YYMMDDD10. 2006-12-01

Four-digit year, dash separators, same as YYMMDD.

YYMONw. Writes dates as a two- or four-digit year followed by the three-letter month
abbreviation. It is right-justified. w can be from 5 to 32, and the default is 7. Use a width of 7
to get a four-digit year. If w is less than 7, a two-digit year will be displayed. If w is larger
than 7, leading spaces will be added. The following table shows the result when the date
value is 15323, which corresponds to December 14, 2001:

Format Name Result
YYMON5.

01DEC

YYMON6.

01DEC

YYMON7.

2001DEC

YYMON10.

2001DEC

Comment
Two-digit year.
Two-digit year, 1 leading space.
Four-digit year.
Four-digit year, 3 leading spaces.

YYQw. Writes date values as a two-digit or four-digit year, followed by the letter Q, and a
single-digit representing the quarter of the year. It is right-justified, and w can be from 4 to

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

41

32. The default width is 6. Use 6 to get a four-digit year, while a width of 4 or 5 will give you
a two-digit year. Specifying a width larger than 6 will only add leading spaces. The following
table shows the result when the date value is 16271, which corresponds to July 19, 2004:

Format Name Result
04Q3

YYQ4.
YYQ5.

04Q3

YYQ6.

2004Q3
2004Q3

YYQ8.

Comment
Two-digit year.
Two-digit year, 1 leading space.
Four-digit year.
Four-digit year, 2 leading spaces.

YYQxw. Writes date values as a two-digit or four-digit year, followed by a separator that
you specify, and a single-digit representing the quarter of the year. x is the letter you use to
indicate the separator according to the table shown here. Unlike the DDMMYYxw.,
MMDDYYxw., and the YYMMDDxw. formats, a blank is not a valid separator with this
format.

x

Character Displayed
in Output

C

colon (:)

D

dash (—)

N

no separator

P

period (.)

S

slash (/)

Comment

w can be from 3–32, with a default of 4. When w is 3 or 4, the
year will be displayed as a two-digit year.

This format is right-justified, and w can be from 4 to 32. The default width is 6. Use a width 6
to get a four-digit year, while 4 or 5 will give you a two-digit year. Specifying a width larger
than 6 will add leading spaces. The following table shows the result when the date value is
15253, which corresponds to October 5, 2001:

42

The Essential Guide to SAS Dates and Times

Format Name Result Comment
YYQN3.

014

Two-digit year, no separator.

YYQC4.

01:4

Two-digit year.

YYQS5.

01/4

YYQP6.

2001.4

YYQD7.

2001–4

Two-digit year, 1 leading space.
Four-digit year.
Four-digit year, 1 leading space.

YYQRw. Writes date values as a two-digit or four-digit year, followed by the letter Q, and
the quarter of the year is represented in Roman numerals. It is right-justified, and w can be
from 6 to 32. The default width is 8. Use 8 to get a four-digit year, while 6 or 7 will give you
a two-digit year. Specifying a width larger than 8 will add leading spaces. The following table
shows the result when the date value is 14099, which corresponds to August 8, 1998:

Format Name Result
YYQR6.

98QIII

YYQR7.

98QIII

YYQR8.

1998QIII

YYQR12.

1998QIII

Comment
Two-digit year.
Two-digit year, 1 leading space.
Four-digit year.
Four-digit year, 4 leading spaces.

YYQRxw. Writes date values as a two-digit or four-digit year, followed by a separator that
you specify, and the quarter of the year is displayed as a Roman numeral. x is the letter you
use to indicate the separator according to the following table. This is another format that
cannot use a blank as the separator.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

x

Character Displayed in
Output

C

colon (:)

D

dash (–)

N

no separator

P

period (.)

S

slash (/)

43

Comment

w can be from 5–32, with a default of 7. When w is 5 or 6, the
year will be displayed as a two-digit year.

This format is right-justified, and w can be from 6 to 32. The default width is 8. Use 8 to get a
four-digit year, while 6 or 7 will display a two-digit year. Specifying a width larger than 8 will
add leading spaces. The following table shows the result when the date value is 17030,
which corresponds to August 17, 2006:

Format Name Result
YYQRP6.

06.III

Comment
Two-digit year.

YYQRS7.

06/III

Two-digit year, 1 leading space.

YYQRN8.

2006III

Four-digit year, 1 leading space, no separator.

YYQRC9.

2006:III

Four-digit year, 1 leading space.

YYQRD10.

2006-III

Four-digit year, 2 leading spaces.

2.4.2 Time Formats
Time formats translate seconds into one of several different ways of displaying time. Only the
TIMEAMPMw.d and TODw.d formats are specific to clock values, displaying clock values from
12:00:00 AM to 11:59:59 PM. All other formats will display hours greater than 23 when
translating a value greater than or equal to 86400, which would be midnight of the following
day. The display of minutes always ranges from 0 to 59, except when you are using the
MMSS. format. The built-in SAS formats always display seconds from 0 to 59.

44

The Essential Guide to SAS Dates and Times

The width specification for time (and datetime) values is different from the one for date formats
because it has to allow for decimal parts of seconds. Instead of w, time and datetime formats
are specified as w.d, where w is the overall width of the entire format, and the d accounts
for the number of digits to the right of the decimal point. w must be greater than (d+1) to
account for the decimal point. As with date formats, each of these formats has its own default
width specification, which is detailed in the description of the format.
HHMMw.d Displays SAS time values as hours:minutes. It is right-justified, and does not
display a leading zero in front of the hours. w can be from 2 to 20, with a default of 5, while
d indicates the number of decimal places to the right of the minutes. As noted above, w must
be greater than d+1, to account for the decimal point. It is different from the TIMEw.d format
in that it does not display seconds. If d is 0 or not present, SAS will round to the nearest
minute. Otherwise, SAS will display the seconds in decimal minutes (seconds/60). The
following table shows the result when the date value is 19886, which corresponds to 5 hours,
31 minutes, and 26 seconds:

Format Name Result

Comment

HHMM2.

5

One leading space because no leading zero.

HHMM4.

5:31

No leading zero, so single-digit hours will fit.

HHMM5.
HHMM8.
HHMM8.2

5:31
5:31
5:31.43

One leading space because there is no leading zero.
Four leading spaces, no leading zero.
26 seconds = .43 minutes, one leading space, no leading
zero.

HOURw.d Displays SAS time values as hours and decimal fractions of hours. It is rightjustified. w can be from 2 to 20, with a default of 2. d is the number of decimal places to the
right of the hours, and w must be greater than d+1 to account for the decimal point. If you do
not specify any decimal places, SAS rounds to the nearest hour. The following table shows the
result when the date value is 53706, which corresponds to 14 hours, 55 minutes and 6
seconds:

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

Format
Name Result

Comment

HOUR2.0

15

Rounded to the nearest hour.

HOUR4.2

14.9

55 minutes, 6 seconds is .92 hours, does not leave enough space for second
decimal place.

HOUR6.2
HOUR8.2

14.92
14.92

45

One leading space.
Three leading spaces.

MMSSw.d Displays SAS time values as minutes and seconds (mm:ss). It is right-justified. w
can be from 2 to 20, with a default of 5. If you do not specify w large enough to fit minutes
and seconds, SAS will round and display the minutes only. d will print decimal fractions (e.g.,
tenths or hundredths) of seconds. w must be greater than d+1 to account for the decimal
point. The following table shows the result when the date value is 37269, which corresponds
to the time 10:21:09 AM (10:21:09):

Format
Name Result
MMSS4.
MMSS5.

621
621

Comment
Leading space.
Two leading spaces.

MMSS8.2

621:09.0

One decimal place for tenths of seconds, because not enough space to fit. A w
of 8 only leaves enough space for a d of 1 because of the decimal point.

MMSS9.2

621:09.00

Two decimal places for hundredths of seconds.

TIMEw.d Displays SAS time values as hours:minutes:seconds. It is right-justified, and does
not print a leading zero in front of the hours. w can be from 2 to 20, with a default of 8,
while d indicates the number of decimal places to the right of the seconds. w must be greater
than d+1 to account for the decimal point. d will print decimal fractions (e.g., tenths or
hundredths) of seconds.
This format is not restricted to a 24-hour day; if hours is greater than 24, then it will display
the value of hours. It is different from the HHMMw.d format in that it does display seconds. If

46

The Essential Guide to SAS Dates and Times

d is 0 or not present, SAS will round to the nearest second. The following table shows the
result when the date value is 29794, which corresponds to the time 8:16:34 AM (8:16:34):

Format
Name Result

Comment

8:16

TIME5.
TIME6.

8:16

TIME7.

8:16:34

TIME8.

Leading space because of the single-digit hour.

No leading spaces; single-digit hour allows the full time to fit in 7 spaces.

8:16:34

TIME9.

8:16:34

TIMEAMPMw.d Displays time in hours:minutes:seconds followed by a space and then AM
or PM. It is right-justified. w can be from 2 to 20, and the default is 11. w must be greater
than d+1, to account for the decimal point. Any time value greater than or equal to 86400
(midnight) will be displayed as the 12-hour clock time of the next day. This format does not
print a leading zero. If you want the seconds to be printed, use at least 11 for the width. The
following table shows the result when the date value is 11923, which corresponds to the time
3:18:43 AM:

Format Name Result
TIMEAMPM7.
TIMEAMPM9.
TIMEAMPM11.
TIMEAMPM14.

3:18 AM

Comment
Single-digit hour, 1 leading space, no seconds.

3:18 AM
3:18:43 AM
3:18:43 AM

Single-digit hour leaves 1 leading space.
Four leading spaces.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

47

TODw.d Displays time in hours:minutes:seconds. It is right-justified. w can be from 2 to 20,
and the default is 11. d is the decimal fraction of seconds, and must be less than w–1, to
account for the decimal point. Any time value greater than or equal to 86400 (midnight of the
next day) will be marked as the 24-hour clock time of the next day. This format does not print
a leading zero. If you want the seconds to be displayed, use 8 for the width. Use at least 10 if
you want decimal fractions of seconds shown. The following table shows the result when the
date value is 75122, which corresponds to the time 8:52:02 PM (20:52:02):

Format Name Result
TOD5.

20:52

TOD8.

20:52:02

TOD11.
TOD14.

20:52:02
20:52:02

Comment

Three leading spaces.
Six leading spaces.

2.4.3 Datetime Formats
Datetime formats translate SAS datetime values into one of several different formats. SAS
datetime values are the number of seconds since midnight, January 1, 1960. You can use a
format to display both the date and time. Again, you need to pay attention to the width
specification in datetime formats because it allows for decimal fractions of seconds. Instead of
w, time and datetime formats are specified as w.d, where w is the overall width of the entire
format, and the d accounts for the number of digits to the right of the decimal point. w must
be greater than (d+1) to account for the decimal point. As with date formats, each of these
formats has its own default width specification, which is detailed in the description of the
format.
Starting with Version 9, there are also formats that will allow you to display just the date or
just the time from a datetime value, eliminating the need to use the DATEPART( ) or TIMEPART()
functions for display purposes. Although these DT formats give the same result as their
corresponding date formats, the results you get will be very different should you use a
datetime format on a date value and vice versa. Datetime formats translate seconds since
midnight, January 1, 1960, while date formats translate days since January 1, 1960.
The following example shows what happens when you use date formats to interpret datetime
values and vice versa. If you translate the SAS date value 16838 using a date format, you

48

The Essential Guide to SAS Dates and Times

will get the correct value of February 6, 2006 (n and o.) However, if you use a datetime
format to translate the same value, you will get 4:40:38 AM on January 1, 1960, which
corresponds to 16,838 seconds after midnight, January 1, 1960 (pand q). In similar
fashion, if you translate the value 1422287527 using a datetime format, you will get 3:52:07
on January 25, 2005 (r and s.) This time, if you try to use a date format to translate this
value, you will get a series of asterisks because the value is too large for the SAS date
algorithm to handle (t and u.) Even if you try to get the month, day and year of this value
using the appropriate functions, it will not work.
Example 2.4.1 The Difference Between Date and Datetime Values in Formats
That Display Dates
DATA _NULL_;
date = 16838;
datetime = 1422287527;
PUT "MMDDYY10. representation of date=" date mmddyy10. /
"MONYY7. representation of date=" date monyy7. /
"DTMONYY7. representation of date=" date dtmonyy. /
"When value of date is used as a SAS *datetime* value, the date
represented is:" date datetime20. /
"DATETIME20. representation of datetime=" datetime datetime20. /
"DTMONYY7. representation of datetime=" datetime dtmonyy7. /
"MONYY7. representation of datetime=" datetime monyy7. /
"When value of datetime is used as a SAS *date* value, the date
represented is:" datetime mmddyy10.;
RUN;

The Log
DATA _NULL_;
date = 16838;
datetime = 1422287527;
PUT "MMDDYY10. representation of date=" date mmddyy10. /
"MONYY7. representation of date=" date monyy7. /
"DTMONYY7. representation of date=" date dtmonyy. /
"When value of date is used as a SAS *datetime* value,
represented is:" date datetime20. //
"DATETIME20. representation of datetime=" datetime datetime20. /
"DTMONYY7. representation of datetime=" datetime dtmonyy7. /
"MONYY7. representation of datetime=" datetime monyy7. /

the

date

(continued on next page)

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

49

"When value of datetime is used as a SAS *date* value, the date represented
is:" datetime mmddyy10.;
RUN;
MMDDYY10. representation of date=02/06/2006

n

MONYY7. representation of date=FEB2006 o
DTMONYY7. representation of date=JAN60 p
When value of date is used as a SAS *datetime* value, the date represented
is: 01JAN1960:04:40:38
q
DATETIME20. representation of datetime=

25JAN2005:15:52:07r

DTMONYY7. representation of datetime=JAN2005

s
t

MONYY7. representation of datetime=*******
When value of datetime is used as a SAS *date* value, the date represented
is: **********
u

With that in mind, here are the formats that are applicable to datetime values.
DATEAMPMw.d Displays datetime values as “ddmonyy(yy):hh:mm:ss.ss xx”, where
dd is the day of the month, mon is the three-letter abbreviation for the month, and yy(yy) is
the two- or four-digit year. A colon follows the date, and the time is represented by
hh:mm:ss.ss, followed by a space and then AM or PM. It is right-justified. w can be from 7
to 40, and the default is 19. d is the decimal fraction of seconds, and must be less than w–1,
to account for the decimal point. w must be at least 13 to print AM or PM. If w is 10, 11, or
12, the time is displayed as a 24-hour clock. Also, if w–d is less than 17, the decimal values
will be truncated to fit the specified field width. This format produces two-digit years for widths
of 19 or less. The following table shows the result when the date value is 1297063816.5,
which corresponds to the time 7:30:17 AM on February 6, 2001:

50

The Essential Guide to SAS Dates and Times

Format Name

Result

Comment

DATEAMPM7.

06FEB01

No room for time.

DATEAMPM12.

06FEB01:07

Two leading spaces, hours is given in 24-hour
clock.

DATEAMPM18.

06FEB01:07:30 AM

Two leading spaces, not enough room for
seconds.

DATEAMPM18.1

06FEB01:07:30 AM

Two leading spaces, not enough room for
seconds.

DATEAMPM19.

06FEB01:07:30:17 AM

DATEAMPM19.1

06FEB01:07:30:17 AM

DATEAMPM25.

DATEAMPM25.1
DATEAMPM29.

06FEB2001:07:30:17 AM

06FEB2001:07:30:16.5 AM
06FEB2001:07:30:17 AM

Not enough room for decimal portion of
seconds.
Four leading spaces, four-digit year, and
rounded seconds.
Two leading spaces, four-digit year, fractional
seconds to 1 decimal place.
Eight leading spaces.

DATETIMEw.d Displays datetime values as ddmonyy(yy):hh:mm:ss.ss, where dd is the day
of the month, mon is the three-letter month abbreviation, and yy(yy) is the two- or four-digit
year. A colon follows the date, and the time is represented by hh:mm:ss.ss. It is similar to
the DATEAMPM. format, except that it uses the twenty-four-hour clock and therefore does not
display AM or PM. It is right-justified. w can be from 7 to 40, and the default is 19. d is the
decimal fraction of seconds, and must be less than w–1 to account for the decimal point. If
w–d is less than 17, the decimal values will be truncated to fit the specified field width. If w–
d is less than 19, this format produces two-digit years. The following table shows the result
when the date value is 1336982668, which corresponds to the time 8:04:28 AM on May
14, 2002:

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

Format
Name

Result

DATETIME16.

14MAY02:08:04:28

DATETIME18.
DATETIME18.1
DATETIME19.

DATETIME19.1
DATETIME20.
DATETIME20.1
DATETIME21.
DATETIME21.2

14MAY02:08:04:28
14MAY02:08:04:28.0

Comment

Two leading spaces.
One decimal place.

14MAY2002:08:04:28

Four-digit year, not enough space for decimal point and
decimal place.

14MAY02:08:04:28.0

w–d =18, so the year is shown as a two-digit year with 1
leading space.

14MAY2002:08:04:28
14MAY2002:08:04:28.0
14MAY2002:08:04:28
14MAY2002:08:04:28.00

51

Two leading spaces.
w–d = 19, so the year is shown as a four-digit year.
Three leading spaces.
Four-digit year, decimal seconds to 2 places.

DTDATEw. Displays datetime values as the numerical day of the month, followed by the
three-letter month abbreviation, and the year without any separating characters. It is rightjustified within the field. w can be from 5–9, the default width is 7. If you want to display fourdigit years, use DTDATE9. The output is identical to the output using the DATE. format. The
difference is that this format will only work correctly with datetime values, while the DATE.
format only works correctly with date values. The following table shows the result when the
date value is 1560379389.4, which corresponds to the time 10:43:09.4 PM on June 11,
2009:

52

The Essential Guide to SAS Dates and Times

Format Name Result
DTDATE5.

Comment

11JUN

DTDATE6.

11JUN

DTDATE7.

11JUN09

Leading space, no year.

DTDATE8.

11JUN09

Leading space.

DTDATE9.

11JUN2009

Four-digit year.

DTMONYYw. Displays the date from a datetime value as the three-letter month abbreviation
followed immediately by the year. There are no separating characters. It is right-justified, and
w can be from 5 to 7, with a default of 5. Specifying 5 or 6 will give you a two-digit year,
while 7 will give you a four-digit year. Although this format appears to produce the same
MMMyy(yy) result as the MONYY. format, the DTMONYY. format can be used only with
datetime values, while the MONYY. format works only with date values. The following table
shows the result 1490086128, which corresponds to the time 8:48:48 AM on March 21,
2007.

Format Name Result Comment
DTMONYY5.

MAR07

DTMONYY6.

MAR07

Leading space.

DTMONYY7.

MAR2007

Four-digit year.

DTWKDATXw. Writes datetime values as day of week name, day, month-name, and year.
It differs from the WEEKDATX. format in that it works on datetime values, not date values. It is
right-justified, and w can range from 3 to 37. The default is 29, which is the maximum width
of a date in this format. Specifying anything longer than 29 will cause leading spaces to be
added. If the width specified is too small to display the complete day of the year and month,
SAS will abbreviate. It will first abbreviate the month and then the day of the week as
necessary. The following table shows the result when the date value is 1393525751.9, which
corresponds to the time 6:29:11.9 PM on February 27, 2004:

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

Format
Name

Result

DTWKDATX3.

Fri

Comment

DTWKDATX11.

Friday

DTWKDATX15.

Fri, 27 Feb 04

Full name of day with leading spaces.

DTWKDATX16. Fri, 27 Feb 2004
DTWKDATX20.
DTWKDATX29.

Friday, 27 Feb 2004
Friday, 27 February 2004
Friday, 27 February 2004

DTWKDATX33.

53

Leading space.
Four-digit year, no leading space.
Full name of day, month abbreviation.
Leading spaces in example, but will fit any
date.
More leading spaces.

DTYEARw. Displays the year for the given datetime value. DTYEARw. is identical in result to
the YEAR. format, but it is used with datetime values instead of date values. It is right-justified,
and w can be from 2 to 4, with a default width of 4. When w is specified as 2 or 3, a twodigit year is used. The following table shows the result when the date value is
1464518782.8, which corresponds to the time 10:46:22.8 AM on May 29, 2006:

Format Name Result Comment
DTYEAR2.

06

DTYEAR3.

06

DTYEAR4.

2006

Two-digit year.
Two-digit year with a leading space.
Four-digit year.

DTYYQCw. Writes date values as a two-digit or four-digit year, followed by a colon, and a
single-digit representing the quarter of the year. It is right-justified, and w can be from 4 to 6.
The default width is 4. Use a width of 6 to get a four-digit year. Use 4 or 5 to get a two-digit
year. This gives you the same result with datetime values as using the YYQC. format would
yield with a date value. The following table shows the result when the date value is
1313917486.6, which corresponds to the time 9:04:46.6 AM on August 20, 2001:

54

The Essential Guide to SAS Dates and Times

Format Name Result Comment
DTYYQC4.

01:3

DTYYQC5.

01:3

DTYYQC6.

2001:3

Two-digit year.
Leading space, two-digit year.
Four-digit year.

2.5 Creating Custom Date Formats Using the VALUE
Statement of PROC FORMAT
In addition to the date and time formats supplied with SAS, you can create your own custom
formats with the FORMAT procedure. With dates and times, you can modify the default
display of an existing SAS format, or create your own using the VALUE or the PICTURE
statement. Here are two examples of modifying the default display of an existing SAS format
using the VALUE statement.
Example 2.5.1 Creating Your Own Format with the VALUE Statement in
PROC FORMAT
An access control company wants a report of the people whose security cards have expired
as of January 1, 2005, and they have the expiration date for each card. Instead of having to
read the report and determine which dates are prior to the cutoff, they want to display any
date prior to January 1, 2005 as Expired. Make sure that you put the format name after the
range, enclosed in brackets.
PROC FORMAT LIBRARY=LIBRARY;
VALUE EXP
LOW-’31DEC2004’D= “Expired”
‘01JAN2005’D - HIGH=[mmddyy10.]; /* Instructs SAS to use the

*/
/* MMDDYY10. format for these */
/* values
*/

RUN;
PROC PRINT DATA= ACCESS;
ID CARD_NUM;
VAR EXP_DATE EXP_DATE_RAW;
FORMAT EXP_DATE EXP. EXP_DATE_RAW DATE9.;
RUN;

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

CARD_NUM
84485598
16205371
63656754
10270040
94822015
27800904
97189418
70815194
50465401
43034970

EXP_DATE
11/14/2006
11/27/2005
01/14/2005
Expired
Expired
Expired
08/14/2005
03/14/2007
Expired
09/28/2005

55

EXP_DATE_RAW
14NOV2006
27NOV2005
14JAN2005
01APR2004
04JUN2004
23OCT2004
14AUG2005
14MAR2007
26MAY2004
28SEP2005

Example 2.5.2 Creating Your Own Format with the VALUE Statement in
PROC FORMAT
In order to be able to drive the next stage in a road race, drivers must finish this stage in ten
minutes or less, and the results are posted. This example shows that you can customize time
formats as well as date formats. To customize datetime formats, you would specify a datetime
format instead of a date or time format.
PROC FORMAT;
VALUE QUALIFY
LOW-’00:10:00’T=[MMSS5.]; /* Instructs the SAS System to use the */

/* MMSS5. format for these values

‘00:10:00’T <- HIGH = “Did Not Qualify”;
RUN;
PROC PRINT DATA=RACERS;
ID NAME;
VAR TIME;
FORMAT TIME QUALIFY.;
RUN;

*/

56

The Essential Guide to SAS Dates and Times

NAME
BORK
BOVA
BRANTLEY
BRICKOWSKI
BURKHART
BURROUGHS
BUTLER

TIME
Did Not Qualify
Did Not Qualify
08:31
08:59
07:10
08:05
Did Not Qualify

2.6 Creating Custom Date Formats Using the PICTURE
Statement of PROC FORMAT
To create your own date and time formats with the PICTURE statement of the FORMAT
procedure, you need to use the DATATYPE= option. DATATYPE can take the DATE, TIME, or
DATETIME arguments to indicate the type of value you are formatting. You then need to define
your display by using one of the following date directives. These directives are case-sensitive.
Table 2.6.1 shows the directives.
Table 2.6.1 Picture Format Date Directives
%a

Locale’s abbreviated weekday name. Locale is defined by the LOCALE= system option.

%A

Locale’s full weekday name. Locale is defined by the LOCALE= system option.

%b

Locale’s abbreviated month name. Locale is defined by the LOCALE= system option.

%B

Locale’s full month name. Locale is defined by the LOCALE= system option.

%d

Day of the month as a decimal number (1–31), with no leading zero. Put a zero between the
percent sign and the “d” to have a leading zero in the display.

%H

Hour (24-hour clock) as a decimal number (0–23), with no leading zero. Put a zero between
the percent sign and the “H” to have a leading zero in the display.

%I

Hour (12-hour clock) as a decimal number (1–12), with no leading zero. Put a zero between
the percent sign and the “I” to have a leading zero in the display.

(continued on next page)

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

57

Table 2.6.1 (continued)
%j

Day of the year as a decimal number (1–366), with no leading zero. Put a zero between the
percent sign and the “j” to have a leading zero in the display.

%m

Month as a decimal number (1–12), with no leading zero. Put a zero between the percent
sign and the “m” to have a leading zero in the display.

%M

Minute as a decimal number (0–59), with no leading zero. Put a zero between the percent
sign and the “M” to have a leading zero in the display.

%p

Locale’s equivalent of either AM or PM. Locale is defined by the LOCALE= system option.

%S

Second as a decimal number (0-–59), with no leading zero. Put a zero between the percent
sign and the “S” to have a leading zero in the display.

%U

Week number of the year (Sunday as the first day of the week) as a decimal number (0–53),
with no leading zero. Put a zero between the percent sign and the “U” to have a leading
zero in the display.

%w

Weekday as a decimal number, where 1 is Sunday, and Saturday is 7.

%y

Year without century as a decimal number (0–99), with no leading zero. Put a zero between
the percent sign and the “y” to have a leading zero in the display.

%Y

Year with century as a decimal number (four-digit year).

%%

The percent character (%).

NOTE:

If you are going to use these directives in a picture format, you will need to
add some code to handle the display of missing values.

The following example creates a format similar to the WORDDATE. format, except that
leading zeros are a part of the date display. Pay special attention to how the picture is
created in line 4. When you are using any of the date directives from the table above, you
must enclose your picture string in single quotes. If you use double quotes, SAS will try to
interpret the directives as macro calls. It will write the format to the catalog, and you will see
warnings in the SAS log when the format is used. It will not work if you have a macro that has
the same name as the format you created.

58

The Essential Guide to SAS Dates and Times

Example 2.6.1 Creating a Picture Format for Dates Using Date Directives
1
2
3

PROC FORMAT;
PICTURE ZWDATE
. - .Z = “NO DATE GIVEN”

5
6
7
8
9
10
11

RUN;
PROC PRINT DATA=PICTEST LABEL;
VAR DATE DATE2;
FORMAT DATE WORDDATE. DATE2 ZWDATE21.;
LABEL DATE = “DATE USING WORDDATE.”
DATE2 = “DATE USING ZWDATE.”;
RUN;

4

LOW - HIGH = ‘%B %0d, %Y’ (DATATYPE=DATE);

Line 3 defines the display for missing values. Without it, you will see the SAS missing value
symbol: either a period (.) or a special missing value. Line 4 gives the picture of how the date
is to be displayed. The zero preceding the day directive (%d) causes the leading zero to be
printed as a part of the date.
The length of the string with the date directives determines the default width of the format. In
this example, the default width is 10, but in order to make sure that all the dates print
correctly, the FORMAT statement in line 8 sets the format width to 21. Following is the
resulting output:

date using worddate. date using zwdate.
June 8, 2002

June 08, 2002

October 17, 2004

October 17, 2004

May 30, 2005

May 30, 2005

.

No Date Given

November 14, 2001

November 14, 2001

March 2, 2003

March 02, 2003

.

No Date Given

April 26, 2005

April 26, 2005

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

59

Example 2.6.2 Using Date Directives and a Picture Format to Bypass
a Function
This example defines a format that will display the date part of datetime values as
mm/dd/yyyy. It is an alternative to using the DATEPART() function and then formatting the
result. In line 3, any missing values are made to display the word Missing. The picture for all
remaining values is defined in line 4. The %0m says that the first characters will be the
numerical value of the month, with a leading zero if necessary, followed by a slash (/).
Similarly, the %0d is interpreted as the numerical day of the month, again with a leading
zero if necessary, followed by a slash. The picture ends with the four-digit year %Y. The
DATATYPE= option tells the format that it will be receiving datetime values to translate. This
format has a default width of ten (2 for the month, 2 for the day, 2 for the slashes, and 4 for
the year.)
1
2
3
4
5
6
7
8
9
10
11
12

PROC FORMAT;
PICTURE avoid
. - .Z = “Missing”
LOW-HIGH = ‘%0m/%0d/%Y’ (DATATYPE=DATETIME);
RUN;
DATA _NULL_;
sample_date = “15dec2004:3:15:00”dt;
PUT ‘SAS datetime value = ‘ sample_date;
PUT ‘SAS formatted with datetime. format =‘ sample_date datetime.;
PUT ‘Using custom format avoid. =‘ sample_date avoid.;
RUN;

The Log
31
32
33
34
35
36

DATA _NULL_;
sample_date = “15dec2004:3:15:00”dt;
PUT ‘SAS datetime value = ‘ sample_date;
PUT ‘SAS formatted with datetime. format =‘ sample_date datetime.;
PUT ‘Using custom format avoid. ‘ sample_date avoid.;
RUN;

SAS datetime value = 1418699700
SAS formatted with datetime. format =15DEC04:03:15:00
Using custom format avoid. =12/15/2004

60

The Essential Guide to SAS Dates and Times

As you can see, the only piece of the datetime value displayed with our custom format is the
date. By specifying the desired pieces of the datetime value as a picture, we have eliminated
the need to use the DATEPART() function. However, remember that the format AVOID. only
changes the display. The value is still a datetime value, not a date value. If you wanted to use
the actual date value (e.g., in a calculation,) you would still have to use the DATEPART( )
function to obtain it from the datetime value.

2.7 The PUT() Function and Formats
What happens if you need to use the formatted value of a date in a character string you’re
assembling? If you use the variable that contains the date value, you’ll get the actual SAS date
value, regardless of any permanent formats assigned to the variable. The PUT() function is
used to store the formatted value of a numeric value in a character variable. The syntax is:

PUT(value,format);
value is a constant or a variable (either numeric or character), and format is the name of a
SAS format. If you are formatting a character variable or constant, then the format you use
must be a character format. Similarly, if you are formatting a numeric value, the format must
be a numeric format. The example below demonstrates:
Example 2.7.1 Using the PUT() Function to Create a Character Date String
DATA _NULL_;
NUMERIC_VALUE = 17422;
B = PUT(NUMERIC_VALUE,MMDDYY10.);
PUT B=;
RUN;
B=09/13/2007

/* b is a character variable of length 10 (defined by the
format width) */

There are a couple of cautions here: first, if you’ve already defined the length of the character
value where you store the result, it has to be at least as long as the format width.

Chapter 2: Displaying SAS Date, Time, and Datetime Values as Dates and Times

61

Secondly, if you want to define the format name at run-time, you must use the
PUTN(value,format-value) function, where value is either a numerical or character value
(it can be a constant, variable, or a valid SAS expression), and format-value is either a
character variable that contains the name of a SAS format, or a character constant that
represents a format name.

62

CHAPTER 3

Converting Dates and Times into
SAS Date, Time, and Datetime Values
3.1 Avoiding the Two-Digit Year Trap ....................................................................... 64
3.2 Using Informats ................................................................................................ 65
3.3 The INFORMAT Statement ................................................................................. 66
3.3.1 Using Informats with the INPUT Statement.................................................. 66
3.3.2 Informats with the INPUT( ) Function .......................................................... 67
3.3.3 When the Informat Does Not Match the Data Being Read ........................... 68
3.4 Listing
3.4.1
3.4.2
3.4.3
3.4.4

and Discussion of Informats...................................................................... 70
Date Informats........................................................................................ 70
Time Informats........................................................................................ 75
Datetime Informats.................................................................................. 77
ANYDT and Its Variants .......................................................................... 77

64 The Essential Guide to SAS Dates and Times

In Chapter 2, I talked about performing the translation from the way SAS understands dates to
the way we express them. How can we do the reverse? After all, if you have a date, time, or
date and time that you need to store or manipulate, it won’t be represented as a SAS date,
time, or datetime value (unless it is coming from another SAS data set). The translation from
common date and/or time terminology to SAS is almost as easy as going the other way, and it
is done in one of two ways: the first was discussed in Section 1.4 with date, time, and datetime
literals. While this works for a small number of these values that are known at compile time,
how do you deal with many dates, or those that are only known at run time? By using
informats to process them.

3.1 Avoiding the Two-Digit Year Trap
Before we get started with any details about informats, let’s talk about using the YEARCUTOFF=
system option as discussed in Section 1.5. Any time that you translate a date or date and time
from common terminology to its SAS value, the YEARCUTOFF= system option will affect the
value that is created if the term that is being translated only has two digits for the year portion.
Those will be interpreted starting with the 100-year period defined in the YEARCUTOFF= system
option. This rule applies to anything that is being translated into a SAS date, time, or datetime
value, including date, time, or datetime literals. The example below shows how date and
datetime literals are affected by the YEARCUTOFF= system option. It displays the actual SAS
date or datetime value represented by the literal along with its formatted value.
Example 3.1.1 Effects of the YEARCUTOFF= System Option on Date and
Datetime Literals
OPTIONS YEARCUTOFF=1920;
DATA _NULL_;
ARRAY a[6] a1-a6;
a1 = "23MAR2005"d;
a2 = "23MAR1905"d;
a3 = "23MAR05"d;
a4 = "19AUG1959:14:45:00"dt;
a5 = "19AUG2059:14:45:00"dt;
a6 = "19AUG59:14:45:00"dt;
DO i = 1 TO 3;
PUT a{i}= +3 a{i}= mmddyy10.;
END;
DO i = 4 TO 6;
PUT a{i}= +3 a{i}= datetime20.;
END;
RUN;

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 65
a1=16518
a2=-20007

a1=03/23/2005
a2=03/23/1905

a3=16518

a3=03/23/2005

a4=-11610900
a5=3144149100

a4=19AUG1959:14:45:00
a5=19AUG2059:14:45:00

a6=-11610900

a6=19AUG1959:14:45:00

/* The variable a3 has a two-digit year.
The year is translated as 2005 because
it falls in the span 1920-2019, and
therefore, a3=a1. */

/* The variable a6 has a two-digit
year. The year is translated as
1959 because it falls in the
span 1920-2019, and therefore,
a6=a4. */

The same thing will happen when you use an informat with a date or datetime that has only two
digits representing the year.

3.2 Using Informats
Informats are the opposite of formats. Where formats take values and display them in a specific
fashion, informats take a series of alphanumeric characters and translate them into a single
value. Dates and times are the best example of applying informats, since SAS date values are
not normally how the majority of the planet expresses dates. A date such as 11/24/05, or 2405-2002 contains non-numeric characters, so they would have to be read as character values,
which is quite a distance from numeric SAS date values. As with formats, you can create (and
store for future use) your own informats if one is not available within SAS to fit your needs.
To apply an informat to a variable, you use the INFORMAT statement. This will cause SAS to
translate a group of characters into a value which is then stored in the variable. Informats are
most commonly used with the INPUT statement as data are being read in or with the INPUT( )
function to translate data that are already in datasets. They are also a property in some SAS/AF
objects.
You specify an informat with the informat name, followed by an optional width specification,
and a period (.) Informats are like formats in that each informat has a default width that SAS
will use if none is specified.

66 The Essential Guide to SAS Dates and Times

3.3 The INFORMAT Statement
The INFORMAT statement is analogous to the FORMAT statement. You use the INFORMAT
statement to associate an informat with a variable in a SAS dataset. You can also remove an
informat that has been permanently associated with the variable by leaving the informat name
blank. You may also use the INFORMAT statement to associate an informat with a variable for
the duration of the procedure (in certain procedures such as the FSEDIT procedure).
INFORMAT date1 mmddyy10.; /* Any character string written into date1
will always be translated with the mmddyy10. informat throughout
SAS */
INFORMAT time3; /* Any informat permanently associated with the
variable time3 will no longer be used to translate character
strings written into time3. */

3.3.1 Using Informats with the INPUT Statement
The basic syntax of an INPUT statement with an informat is:

INPUT @1 date1 mmddyy10.;
First, you will usually specify a starting column. The default starting column is 1, but you can
specify the starting column with the @ sign, followed by the column number. If you do not, the
starting column will be set to the current location of the input pointer. You should also specify a
width for the informat to indicate how many characters are to be read. The above INPUT
statement will read the first ten characters in a line, starting at the first character in a data line,
and SAS will expect it to look like mmsdds(yy)yy, where mm is the month from 01–12, s
represents a separator character, dd is a day from 01–31, and (yy)yy is a two- or four-digit
year. The following example demonstrates that the separator character does not have to be the
same on every line, and the field does not have to be exactly ten characters long.
Example 3.3.1 INPUT Statement Example
DATA informats_are_smart;
INPUT @1 date MMDDYY10.;
unformatted_date = date;
DATALINES;
10/17/2002
05-04-59

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 67
3-1-1940
;
RUN;
PROC PRINT;
FORMAT DATE MMDDYY10.;
RUN;

Obs

Date

Unformatted_date

1 10/17/2002

15630

2 05/04/1959

-242

3 03/01/1940

-7245

As you can see in the above example, the characters in each line of the DATALINES statement
were converted to a SAS date value. It doesn’t matter that lengths of the character strings
representing date in the data are different. It is only an issue if you have more characters in the
date string than the ten columns you’ve allocated for the date. The length of the informat must be
long enough to read all of the characters in the date string.
If the characters read do not match that layout (e.g., June 26, 1994), or if the informat would
yield an impossible value (e.g., February 31) SAS will set the value of the variable date1 to
missing, and set the system variable _ERROR_ to 1. In general, you should know the layout of
the characters before selecting an informat. In SAS Version 9, if you do not know the layout of
the dates, the ANYDT family of informats (Section 3.4.4) can help.

3.3.2 Informats with the INPUT() Function
The INPUT( ) function is the parallel to the PUT( ) function, and it stores a numeric or character
value as a numeric or character variable. The type of the result depends on the type of the
informat that is used. A character informat (one that begins with a $) will return a character
value. All of the informats used with dates, times, and datetimes are numeric; therefore, the
variable returned is numeric. The syntax is:

INPUT(character-value,informat-name);
If you want to define the informat that is to be applied during a SAS job (at run-time), you will
need to use the INPUTN(character-value,informat-value) function (or INPUTC(), if you

68 The Essential Guide to SAS Dates and Times

want to produce a character variable) instead. informat-value represents a character
variable or character constant that contains an informat name, while the INPUT( ) function needs
an actual informat name. Make sure that you have defined the width of the informat so that it is
long enough to capture all the characters in the entire character variable. The following
example illustrates the use of the INPUT() function:
Example 3.3.2 INPUT() Function Example
DATA _NULL_;
a = “15-NOV-2003”;
b = INPUT(a,DATE11.);
PUT B=;
RUN;
B=16024

The INPUT( ) function translates the date in the character variable a into its equivalent SAS date
value and stores it in the numeric variable b. The DATE11. informat accounts for the length of
the character variable.

3.3.3 When the Informat Does Not Match the Data Being Read
Informats, like formats, are separated into classes according to the type of data that are being
read. In most cases, if you use the wrong informat for the data type, informats will return an
error (set the SAS automatic variable _ERROR_ to 1), and the value of the variable being read
will be set to missing.
This behavior differs from formats in that if you use the wrong type of format to display a value
(e.g., if you use a date format to display a time value), no error will occur, and at worst, you
will get a warning in the SAS log. However, incorrectly specifying a format will most likely
cause the display to be incorrect. Example 3.3.3 shows what happens when you try to use an
informat that does not match the character string that you are trying to process.

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 69

Example 3.3.3 Using the Wrong Informat
DATA bad_informat;
INPUT @1 date datetime18.;
DATALINES;
11-06-1988
8-25-2004
4-24-2005
;;;;
RUN;

The Log
1
2
3

DATA bad_informat;
INPUT @1 date datetime18.;
DATALINES;

NOTE: Invalid data for date in line 4 1-18.
RULE:
----+----1----+----2----+----3----+----4----+----5----+----6----+
4
11-06-1988
date=. _ERROR_=1 _N_=1
NOTE: Invalid data for date in line 5 1-18.
5
8-25-2004
date=. _ERROR_=1 _N_=2
NOTE: Invalid data for date in line 6 1-18.
6
4-24-2005
date=. _ERROR_=1 _N_=3
NOTE: The data set WORK.BAD_INFORMAT has 3 observations and 1 variables.
NOTE: DATA statement used (Total process time):
real time
0.53 seconds
cpu time
0.03 seconds
7
;;;;
8
RUN;

70 The Essential Guide to SAS Dates and Times

The Resulting SAS Dataset
Obs date
1
.
2
.
3
.

As you can see in the above example, using the DATETIME. informat to process a series of
character strings that do not represent datetimes produces a note in the log. It also sets the
automatic variable _ERROR_ to 1 for each record where it encountered a mismatch between the
informat specified and the data it attempted to read. The end result is that the value of the date
variable in your output dataset is missing because SAS was not able to process the characters
using the specified informat. Remember to always check your log and your dataset after
reading a text file.

3.4 Listing and Discussion of Informats
Each discussion of an informat in this section will provide an explanation of the informat, its
length specification and the text it is designed to process. Each section is accompanied by a
table that gives examples of the text that is to be processed, along with the informat (and its
length specification), and the resulting SAS date, time, or datetime value.

3.4.1 Date Informats
DATEw. Reads dates in the form ddmonyy(yy), where dd represents the day of the month,
mon is the three-letter month abbreviation, and yy(yy) is the two- or four-digit year. The
default value of w is 7, but you should specify 9 if you are reading four-digit years. dd, mon,
and yy(yy) can be separated by blanks or special characters. If you separate them, you must
account for the blanks (or special characters) in the width specification. If you have blanks after
the month and the day, then you need to have a width of 9 for two-digit years, or 11 for fourdigit years. If the leading zero for dd is missing, it has no effect on the value. The following
table gives examples of how to apply this informat to yield the SAS date value that corresponds
to the text shown in each line.

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 71

When the characters being
read are:

Use the
Informat

And the result is:

20oct95

date7.

13076

8 jan 2004

date11.

16078

07-may-1960

date11.

127

DDMMYYw. Reads dates of the form ddmmyy(yy), where dd represents the day of the
month, mm represents the number of the month, and yy(yy) is the two- or four-digit year. The
default value of w is 6, but you should specify 8 if you are reading four-digit years. dd, mm,
and yy(yy) can be separated by blanks or special characters. If you separate them, you must
account for the separating characters in the width specification. If you have blanks after the
month and the day, then you need to have a width of 8 for two-digit years, or 10 for four-digit
years. SAS will do its best to decipher the string if no separators are used, but some dates
cannot be processed, e.g., 2112008. Without place-holding zeros or separators, there is no
way to know if the date is 21 January, 2008, or 2 November, 2008. The following table gives
examples of how to apply this informat to yield the SAS date value that corresponds to the text
shown in each line.

When the characters
being read are:

Use the
Informat

And the result is:

140390

ddmmyy6.

11030

06/09/05

ddmmyy8.

16685

22-04-2003

ddmmyy10.

15817

JULIANw. Translates a Julian date in the form YY(yy)ddd, with the two- or four-digit year
preceding the zero-filled Julian day of the year. It is right-justified. w can be from 5 to 32, and
the default is 5. If you specify 5, the year portion of the Julian date is two digits long. If you
specify 7 or more, the year portion is four digits long. Zeros must fill the space between the year
and day values; for example, the fifth day of the year must be given as 005. Any date
preceding the year 1582 on the Gregorian calendar cannot be read as a Julian value. The
following table gives examples of how to apply this informat to yield the SAS date value that
corresponds to the text shown in each line.

72 The Essential Guide to SAS Dates and Times

When the characters
being read are:

Use the
Informat

And the result is:

77284

(October 11, 1977)

julian5.

6493

2004005 (January 5, 2004)

julian7.

16075

2002111 (April 21,2002)

julian10.

15451

MMDDYYw. Reads dates of the form mmddyy(yy), where mm represents the number of
the month, dd represents the day of the month, and yy(yy) is the two- or four-digit year. The
default value of w is 6, but you should specify 8 if you are reading four-digit years. dd, mm,
and yy(yy) can be separated by blanks or special characters. If you separate them, you must
account for the blanks in the width specification. If you have blanks after the month and the day,
then you need to have a width of 8 for two-digit years, or 10 for four-digit years. SAS will do its
best to decipher the string if no separators are used, but some dates cannot be processed, e.g.,
1272003. Without place holding zeros or separators, there is no way to know if the date is
January 27, 2003, or December 7, 2003. The following table gives examples of how to apply
this informat to yield the SAS date value that corresponds to the text shown in each line.

When the characters
being read are:

Use the
Informat

And the result is:

041705

mmddyy6.

16543

1/15/2004

mmddyy10.

16085

08281996

mmddyy10.

13389

MONYYw. Reads dates of the form monyy(yy), where mon is the three-letter month
abbreviation, and yy(yy) is the two- or four-digit year. Using this informat will set the SAS date
value that corresponds to the first day of the month. The default value of w is 5, but you should
specify 7 if you are reading four-digit years. The following table gives examples of how to
apply this informat to yield the SAS date value that corresponds to the text shown in each line.

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 73

When the characters
being read are:

Use the
Informat And the result is:

JAN05

monyy5.

16437

(January 1, 2005)

dec1920

monyy7.

-14275

(December 1, 1920)

aug2020

monyy7.

22128

(August 1, 2020)

PDJULG4. Reads a packed Julian date in hexadecimal format for IBM computers. The width
specification is always 4, because the Julian date is parsed as follows: the four-digit Gregorian
year is written in the first two bytes, and the three-digit integer that represents the day of the
year is in the next one-and-a-half bytes. The last half-byte contains all binary 1’s, which indicates
the value is positive. There is no example given for this informat because packed decimal Julian
dates yield non-printable characters.
PDJULIw. Also reads a packed Julian date in hexadecimal format for IBM computers. It differs
from the PDJULG. informat in that it expects the two digits of the century in the first byte,
followed by two digits of the year in the second byte. The next one-and-a-half-bytes store the
three-digit integer that corresponds to the day of the year, while the last half-byte is filled with
hexadecimal 1’s, representing a positive number. The century and year are calculated by
subtracting 1900 from the four-digit Gregorian year. Once again, there is no example, since
packed decimal Julian dates yield non-printable characters.
YYMMDDw. Reads dates of the form yy(yy)mmdd, where yy(yy) is the two- or four-digit
year, mm represents the number of the month, and dd represents the day of the month. The
default value of w is 6, but you should specify 8 if you are reading four-digit years. yy(yy),
mm, and dd can be separated by blanks or special characters. If you separate them, you must
account for the separating characters in the width specification. If you have blanks after the
month and the day, then you need to have a width of 8 for two-digit years, or 10 for four-digit
years. The following table gives examples of how to apply this informat to yield the SAS date
value that corresponds to the text shown in each line.

74 The Essential Guide to SAS Dates and Times

When the characters
being read are:

Use the
Informat And the result is:

041205

yymmdd6.

16410

20030227

yymmdd8.

15763

20030227

yymmdd10.

15763

1978-07-11

yymmdd10.

6766

YYMMNw. Reads dates of the form yy(yy)mm, where yy(yy) is the two- or four-digit year,
and mm represents the number of the month. The day is automatically set to 1. The default
value of w is 4, but you should specify 6 if you are reading four-digit years. The N in the
informat name is necessary. You may not use any separating characters between the month and
the year. This informat will produce a date value that is equal to the first day of the month given.
The following table gives examples of how to apply this informat to yield the SAS date value
that corresponds to the text shown in each line.

When the characters
being read are:

Use the
Informat And the result is:

7805

yymmn4.

6695

200504

yymmn6.

16527

(April 1, 2005)

199211

yymmn6.

11993

(November 1, 1992)

(May 1, 1978)

YYQw. Reads dates of the form yy(yy)Qq, where yy(yy) is the two- or four-digit year
followed by the letter Q and q is a number from 1 to 4, indicating the quarter of the year. The
date value produced by this informat will correspond to the first day of the given quarter. Use 6
for w if you are reading four-digit years, or 4 if you are reading two-digit years. The default w
in Version 6 is 4, while Versions 7 and above have a default w of 6. The following table gives
examples of how to apply this informat to yield the SAS date value that corresponds to the text
shown in each line.

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 75

When the characters
being read are:

Use the
Informat

And the result is:

04Q1

yyq4.

16071

(January 1, 2004)

2000Q3

yyq6.

14792

(July 1, 2000)

1985Q2

yyq6.

9222

2003Q4

yyq6.

15979

(April 1, 1985)
(October 1, 2003)

3.4.2 Time Informats
MSEC8. Reads IBM mainframe time values accurate to the nearest millisecond. The width is 8
because the OS TIME macro and STCK system instructions store their time values in 8 bytes.
PDTIME4. Converts packed decimal time values contained in SMF and RMF records produced
by IBM mainframe systems to SAS time values. The width is shown as 4 because SMF and RMF
records are 4 bytes long.
RMFDUR4. Converts IBM SMF duration records into SAS time values. The width is shown as 4
because SMF records are 4 bytes long.
STIMERw. Reads times produced by the STIMER system option in the SAS log. This informat
has no default width. It reads times and interprets them based on colons and decimal points. If
there is one colon, the first two digits are minutes, and the last two are seconds. If there are two
colons, the digits preceding the first colon are hours, the next set of two digits are minutes, and
the last two are seconds. If there is a decimal point, the value following the decimal point is
translated as a decimal fraction of seconds. It can read time values in the following formats,
where hh corresponds to hours, mm corresponds to minutes, ss corresponds to seconds, and
ff corresponds to decimal fractions of seconds:
ss
ss.ff
mm:ss
mm:ss.ff
hh:mm:ss
hh:mm:ss.ff

76 The Essential Guide to SAS Dates and Times

DATA _NULL_;
INPUT A STIMER11.;
PUT A;
DATALINES;
33
n
51.60
o
14:05
p
3:11.03 q
1:19:21 r
11:46:17.74 s
RUN;

Corresponding SAS Time Values
n
33
o
51.6
p
845
q
191.03
r
4761
s
42377.74

TIMEw. This will read times in the form hh:mm:ss.ff, where hh indicates the hours, mm is
minutes, and ss is the number of seconds. ff indicates decimal fractions of seconds. Both
seconds and their decimal fractions are assumed to be zero if they are not present. This
informat can read AM and PM time values. If hh is greater than 24, and/or mm and ss are
greater than 60, the time value read will give the correct number of seconds, even if it is
greater than 86399.99 (the number of seconds in a day.) It will parse the time value
according to the number of colons in the input string as shown in the table below.

hh
hh:mm
hh:mm:ss
hh:mm:ss.ff
The program below demonstrates how the informat works, with the SAS time values that
correspond to the input line on the right hand side.
DATA _NULL_;
INPUT A TIME10.;
PUT A;
DATALINES;
124:46
14:11:03.3
1:27 PM
6:30 AM
18:53
RUN;

n
o
p
q
r

Corresponding SAS Time Values
n 449160
o 51063.3
p 48420
q 23400
r 67980

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 77

TU4. Converts IBM mainframe timer units to SAS time values. It is used when reading IBM
mainframe timer values under other operating systems. The width is 4 because the OS TIME
macro returns a 4-byte word.

3.4.3 Datetime Informats
DATETIMEw. This reads SAS datetime values. The datetime value must be in the form
ddmonyy(yy), followed by a blank or a special character, and then the time in the format
hh:mm:ss.ff. dd represents the day of the month, mon is the three-letter month
abbreviation, and yy(yy) is the two- or four-digit year. hh indicates the number of hours,
mm is the number of minutes, and ss is the number of seconds. ff indicates fractional parts of
seconds. Both seconds and fractional seconds are assumed to be zero if they are not present.
w can be from 13 to 40, with a default of 18.
If you use a two-digit year, SAS will apply the YEARCUTOFF= system option in translating the
year. This informat can also read AM and PM time values.
DATA _NULL_;
INPUT A DATETIME22.;
PUT A;
DATALINES;
22APR2004 5:23 PM
n
22APR2004-17:23
o
22APR2004:05:23:15 PM
22APR2004/17:23:15.6
RUN;

p
q

n
o
p
q

Corresponding SAS Datetime
Values
1398273780
1398273780
1398273795
1398273795.6

3.4.4 ANYDT and Its Variants
The release of SAS 9 has addressed a problem with the processing of dates and times that
has plagued SAS since the beginning. While informats handle the translation of a string of
characters into SAS date and time values, in order to use them you had to know what the
string of characters looked like before you processed them. Add to that the many ways that
dates and times are represented, and you wind up with the potential for error, and using more
than a few PUT _INFILE_ statements over the years. There is now a series of three informats
that will intelligently and, for the most part, successfully enable you to avoid this problem.

78 The Essential Guide to SAS Dates and Times

The potential for confusion exists with DDMMYY, MMDDYY, and YYMMDD values, especially
in the presence of two-digit-year values. Remember that the SAS system option DATESTYLE
(detailed in Section 1.5) indicates how such confusions will be resolved. Once again, the
possible values for the DATESTYLE= system option are shown in Table 3.4.1.
Table 3.4.1 Values for the DATESTYLE= system option

MDY

Sets the default order as month, day, year.
“11-01-06” would be translated as
November 1, 2006.

YDM

Sets the default order as year, day, month.
“11-01-06” would be translated as June 1,
2011.

MYD

Sets the default order as month, year, day.
“11-01-06” would be translated as
November 6, 2001.

DMY

Sets the default order as day, month, year.
“11-01-06” would be translated as January
11, 2006.

YMD

Sets the default order as year, month, day.
“11-01-06” would be translated as
January 6, 2011.

DYM

Sets the default order as day, year, month.
“11-01-06” would be translated as June 11,
2001.

LOCALE
(default)

Sets the default value according to the LOCALE= system option. When the default value for the
LOCALE= system option is “English_US”, this sets DATESTYLE to MDY. Therefore, by default,
“11-01-06” would be translated as November 1, 2006.

The ANYDTDTE., ANYDTDTM., and ANYDTTME. informats will translate dates, datetime
values, and time values, respectively, into their corresponding SAS values. This translation will
be performed without having to know the representation of these dates, datetime, and time
values in advance. There are limits to the types of representations these informats will process,
and using these informats will take more CPU time than if you used one of the regular
informats to process your data.

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 79

ANYDTDTEw. This will translate data that can be read with the following informats: DATE,
DATETIME, DDMMYY, JULIAN, MMDDYY, MONYY, TIME, YYMMDD, or YYQ into SAS date
values. Note that it can extract date values from a datetime value. However, if only a time
value is given, the date is assumed to be January 1, 1960. w can range from 5 to 32, and
the default width is 9.
The following program illustrates the use and function of this informat. The table that follows
the program was created from the output file from the program. The table details each of the
character strings that are used as input from the DATALINES statement in the program.
OPTIONS DATESTYLE=MDY;
DATA _NULL_;
FILE “ANYDTDTE.TXT”;
RETAIN TAB ‘09’X;
INPUT A $20. @
@1 B ANYDTDTE20.; /* RE-READ SAME DATA LINE INTO A NUMERIC VARIABLE
USING THE ANYDTDTE. INFORMAT */
PUT A TAB B TAB B WORDDATE.;
DATALINES;
05172004
20040517
2004Q1
051704
17052004
170504
17MAY2004:15:12:06
15:12:06
2004138
MAY2004
17MAY2004
;
run;

80 The Essential Guide to SAS Dates and Times

Input String

SAS
Date
Value

Formatted
Value

05172004

16208

May 17, 2004

20040517

16208

May 17, 2004

2004Q1

16071

January 1, 2004

051704

16208

May 17, 2004

17052004

170504

.

20943

Notes

.

The input string cannot be translated reliably
regardless of the order of precedence. The
date could be April 20, 1705
(04/20/1705), or May 17, 2004. SAS
will try to apply the MMDDYY. informat
because of the DATESTYLE option in effect,
but 17 is an invalid value for month.

May 4, 2017

As opposed to the example above with a
four-digit year, this can be translated.
However, this is greatly affected by the
DATESTYLE option in effect. See the special
caution in Example 3.4.1 at the end of this
section on the ANYDT informats.

17MAY2004:15:12:06 16208

May 17, 2004

15:12:06

0

January 1, 1960

Time values are translated as seconds after
midnight, 1/1/1960, so the date is
1/1/1960.

2004138

16208

May 17, 2004

Julian date

MAY2004

16192

May 1, 2004

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 81

ANYDTDTMw. This will translate data that can be read with the following informats: DATE,
DATETIME, DDMMYY, JULIAN, MMDDYY, MONYY, TIME, YYMMDD, or YYQ, and create
SAS datetime values. If only a time value is given, the date is assumed to be January 1, 1960.
w can range from 1 to 32, and the default width is 19. The following table uses the same
input data as is used in the ANYDTDTE. informat example above.

Input String

SAS Datetime Value Formatted Value

05172004

1400371200

17MAY04:00:00:00

20040517

1400371200

17MAY04:00:00:00

2004Q1

1388534400

01JAN04:00:00:00

051704

1400371200

17MAY04:00:00:00

17052004

.

The input string cannot be translated reliably
regardless of the order of precedence.

1809475200

As opposed to the example above with a four-digit
year, this can be translated. However, this is greatly
affected by the DATESTYLE option in effect. See the
special caution in Example 3.4.1 at the end of this
section on the ANYDT informats.

170504

17MAY2004:15:12:06 1400425926

17MAY04:15:12:06

15:12:06

54726

01JAN60:15:12:06

2004138

1400371200

17MAY04:00:00:00

MAY2004

1398988800

01MAY04:00:00:00

17MAY2004

1400371200

17MAY04:00:00:00

82 The Essential Guide to SAS Dates and Times

ANYDTTMEw. This will take data that can be read with the DATE, DATETIME, DDMMYY,
JULIAN, MMDDYY, MONYY, TIME, YYMMDD, or YYQ informats and translate it to SAS time
values. ANYDTTMEw. can obtain time values from a datetime value. However, if only a date
value is given, the time is assumed to be 12:00 AM. w can range from 1 to 32, and the
default width is 8. This table uses the same input data that was used in the ANYDTDTE.
informat example.

Input String

SAS Time Value Formatted Value

05172004

0

12:00:00AM

20040517

0

12:00:00AM

2004Q1

0

12:00:00AM

051704

0

12:00:00AM

17052004

.

The input string cannot be translated reliably
regardless of the order of precedence.

170504

0

12:00:00AM

17MAY2004:15:12:06 54726

3:12:06PM

15:12:06

54726

3:12:06PM

2004138

0

12:00:00AM (Julian date)

MAY2004

0

12:00:00AM

17MAY2004

0

12:00:00AM

Example 3.4.1 Be Careful When You Use the ANYDT. Series of Informats
The ANYDT. informats are not perfect. Let’s look a little more closely at the interaction between
the DATESTYLE= system option and the ANYDTDTE. informat. As noted in the above
examples, the characters 17052004 cannot be reliably translated, so SAS returns a missing
value regardless of what DATESTYLE= option is in effect. However, it was also shown that
170504 can be translated. The SAS value you get for those characters varies widely
depending on the DATESTYLE= option.

Chapter 3: Converting Dates and Times into SAS Date, Time, and Datetime Values 83

When OPTIONS DATESTYLE=myd, '170504' is translated as: . (missing)
When OPTIONS DATESTYLE=ymd, '170504' is translated as: 20943 (05/04/2017)
When OPTIONS DATESTYLE=ydm, '170504' is translated as: . (missing)
When OPTIONS DATESTYLE=dmy, '170504' is translated as: 16208 (05/17/2004)
When OPTIONS DATESTYLE=dym, '170504' is translated as: . (missing)
When OPTIONS DATESTYLE=mdy, '170504' is translated as: 20943 (05/04/2017)

Three of the DATESTYLE settings yield missing values, while two yield the expected date
values. But for some reason, the MDY setting (italics) gives you the value you’d expect from the
YMD setting, and this may not be what you want.
While it is always a good idea to check all data that you are converting to SAS from another
source and especially when you are converting dates, times, and date-time values, it is critical
if you are using the ANYDT. informats.

84

CHAPTER 4

Date and Time Functions
4.1 Current Date and Time Functions........................................................................ 86
4.2 Extracting Pieces from SAS Date, Time, and Datetime Values ................................ 86
4.3 Creating Dates, Times, and Datetimes from Numbers ........................................... 89
4.4 Calculating Intervals ......................................................................................... 93
4.4.1 Calculating Elapsed Time with DATDIF( ) and YRDIF() ................................. 93
4.4.2 The Basics of SAS Intervals...................................................................... 96
4.4.3 The Interval Calculation Functions: INTCK and INTNX ................................ 98

86 The Essential Guide to SAS Dates and Times

SAS has several functions to manipulate dates, times, and datetime values. The functions can
be categorized according to what they do. You can obtain the current date, time, or datetime
(as specified by the computer’s clock). You can also easily extract pieces of dates, times or
datetimes as numerical values from their corresponding SAS values, or you can assemble SAS
date, time, and datetime values from SAS variables or constants. Another set of functions
operates with intervals such as weeks or months.

4.1 Current Date and Time Functions
Current date and time functions have no arguments, and return SAS values as noted in the
following table. The values are obtained from the operating system’s clock.
DATE( ) , TODAY( )

These functions are identical, and they both return the current date as a SAS
date value.

TIME( )

This returns the current time as a SAS time value.

DATETIME( )

This returns the current date and time as a SAS datetime value.

4.2 Extracting Pieces from SAS Date, Time, and
Datetime Values
The extraction functions all use a single argument (represented by arg in the following table),
which represents a SAS date, time, or datetime value. This can be either a SAS variable name
or the appropriate constant. If two-digit year values are used, the result will be subject to the
YEARCUTOFF= option value in effect. They all return a numeric value as the result. The
following table gives examples of how to apply each function, along with relevant comments
for each example:

Chapter 4: Date and Time Functions 87

Function Name

Explanation

Example

DATEPART(arg)

Extracts the date from a SAS
datetime value as a SAS date value.

DATEPART(‘21MAR1998:17:07:00’dt) = 13959
(March 21, 1998)

DAY(arg)

Extracts the number of the day of
the month from a SAS date value.

DAY(“14OCT2008”d) = 14

HOUR(arg)

Extracts the hour from a SAS time
value.

HOUR(“7:35:00”t) =7

JULDATE(arg)

Extracts the Julian date from a SAS
date value. It will return a four- or
five-digit value if the year portion of
the date falls within the 100-year
span defined by the YEARCUTOFF=
option. In order to be Y2K
compliant, you should use the
JULDATE7(); function.

JULDATE(“09MAY2004”d) = 4130
(Result is returned as a numeric value, so there
are no leading zeros.)

Extracts the Julian date with a fourdigit year from a SAS date value.
This is the Y2K-compliant version
since it always returns a seven-digit
number, regardless of the year.

JULDATE7(“09MAY2004”d) = 2004130

MINUTE(arg)

Extracts the minutes from a SAS time
value.

MINUTE(“12:17:43 PM”t) = 17

MONTH(arg)

Extracts the numerical month from a
SAS date value.

MONTH(“22AUG2005”d) = 8

QTR(arg)

Extracts the quarter of the year from
a SAS date value.

QTR(“8JAN2000”d) = 1

SECOND(arg)

Extracts the seconds from a SAS
time value.

SECOND(“2:17:43”t) = 43

JULDATE7(arg)

JULDATE(“09MAY1890”d) = 1890129

JULDATE7(“09MAY1890”d) = 1890129

(continued on next page)

88 The Essential Guide to SAS Dates and Times

Function Name

Explanation

Example

TIMEPART(arg)

Extracts the time portion from a SAS
datetime value as a SAS time value.

TIMEPART(“06SEP1976:13:36:33”dt) = 48993
(1:36:33 PM)

WEEK(arg)

Extracts the week number from a
SAS date value, where Sunday is
the first day of the week.

WEEK(“02JAN2005”d) = 1

(Version 9.1.3)

Extracts the week number from a
SAS date value. descriptor can be
“U”, “V”, or “W” (case-insensitive),
and it refers to the algorithm used to
calculate the first week of the year.

WEEK(“02JAN2005”d,”U”) = 1
January 2, 2005 was a Sunday, so the first week
of the year has started.

WEEK(arg,descriptor)

The U algorithm calculates weeks
based on Sunday being the first day
of the week.
The V algorithm calculates weeks to
the ISO standard. Monday is the
first day of the week, and the first
week of the year is defined as the
one that contains both January 4
and the first Thursday of the year.

WEEK(“02JAN2005”,d,”V”) = 53
This week is defined as being the 53rd week in
2004, because it doesn’t contain the first
Monday or Thursday of the year.
WEEK(“02JAN2005”d,”W”) = 0
The year 2005 has started, but weeks are
calculated with Monday as the first day of the
week. Therefore, the first week of 2005 doesn’t
start until January 3, 2005, so this is week 0 of
2005.

The W algorithm calculates weeks
based on Monday being the first
day of the week without restriction.
WEEKDAY(arg)

Extracts the number of the day of
the week, where Sunday=1,
Monday=2, etc. from a SAS date
value.

WEEKDAY(“14APR1999”d) = 4
(Wednesday, April 14, 1999)

YEAR(arg)

Extracts the year from a SAS date
value. If you use a date constant (as
in the example) and not a SAS date
value, it is important to remember
that the YEARCUTOFF option affects
two-digit years.

If OPTIONS YEARCUTOFF=1920;
YEAR(“19JUL10”d) = 2010
YEAR(“19JUL1910”d) = 1910

Chapter 4: Date and Time Functions 89

4.3 Creating Dates, Times, and Datetimes from Numbers
This series of functions will create SAS date, time, and datetime values from numerical
variables or constants.
DATEJUL(julian-date); creates a SAS date value from a numeric value representing a
Julian date. julian-date must be of the type yy(yy)ddd, where yy(yy) is two or four digits
representing the year, and ddd must be between 1–365 (366 if a leap year.) If you use two
digits for the year, the YEARCUTOFF= option will be used to determine the century. The
following table gives examples of how to apply this function, along with relevant comments for
each example:

Sample Function Call

SAS Date
Value

Formatted
with
MMDDYY10.
Format

OPTIONS YEARCUTOFF=1920;

–13959

10/13/1921

With the YEARCUTOFF
value of 1920, the 21 is
interpreted as 1921.

22566

10/13/2021

If YEARCUTOFF is 2000,
the 21 is interpreted as
2021.

DATEJUL(2005174)

16610

06/23/2005

DATEJUL(1989005)

10597

01/05/1989

DATEJUL(00368)

.

.

DATEJUL(21286)
OPTIONS YEARCUTOFF=2000;
DATEJUL(21286)

Comments

368 is not a valid value
for a Julian day, so the
function returns a missing
value.

90 The Essential Guide to SAS Dates and Times

DHMS(date,hour,minute,second); creates a SAS datetime value. All four arguments are
required. date is a SAS date value, which can be either a numeric value or a date constant.
If you use a two-digit year in a date constant, the date will be translated according to the
YEARCUTOFF= option. hour is a numeric variable or constant, minute is a numeric variable
or constant, and second is a numeric variable or constant. Hour, minute and second are
not restricted to their clock times; therefore, hour can be greater than 24, while minute and
second can be greater than 60. The following table gives examples of how to apply this
function, along with relevant comments for each example:

Sample Function Call

Datetime
Value

Formatted with
DATETIME.
Format

DHMS(“08JUN1995”d,15,24,0)

1118244240

08JUN1995:15:24:00

DHMS(“10SEP1999”d,3,0,0)

1252551600

10SEP1999:03:00:00

DHMS(“02FEB2004”d,11,54,15)

1391342055

02FEB2004:11:54:15

DHMS(“30JUN1992”d,8,7,93)

1025510913

30JUN1992:08:08:33

DHMS(“26APR2003”d,23,0,28)

1367017228

26APR2003:23:00:28

Comments

The value 93 is just an
argument. The function
ultimately returns the
datetime value in
seconds and the
formatted value
converts the result.
Therefore, 93 seconds
becomes 1 minute, 33
seconds, which adds 1
to the minute value of
7, and reduces the
seconds to 33.

Chapter 4: Date and Time Functions 91

HMS(hour,minute,second); creates a SAS time value. hour is a numeric variable or
constant, minute is a numeric variable or constant, and second is a numeric variable or
constant. All three arguments must be present. hour, minute, and second are not restricted
to their clock times, so that hour can be greater than 24, while minute and second can be
greater than 60. The following table gives examples of how to apply this function, along with
relevant comments for each example:

Sample
Function
Call

Time
Value

Formatted
with
TIME.
Format

Formatted
with
TIMEAMPM.
Format
Comments

HMS(18,0,9)

64809

18:00:09

6:00:09 PM

HMS(7,45,80)

27980

7:46:20

7:46:20 AM

HMS(15,03,35.56)

54215.56

15:03:36

3:03:36 PM

HMS(8,17,33)

29853

8:17:33

8:17:33 AM

HMS(21,14,28)

76468

21:14:28

9:14:28 PM

The time is not displayed as
“7:45:80” because the
value is returned as the total
number of seconds, and the
format is applied to that.
Neither the TIME. nor the
TIMEAMPM. formats display
minute or second values
greater than 59.

MDY(month,day,year);
creates a SAS date value from the arguments. All three
arguments are required. month is a numeric variable or constant, day is a numeric variable
or constant, and year is a numeric variable or constant. If year is two digits, the century will
be determined by the YEARCUTOFF= option. If a value given for any of the arguments is not
valid, such as MDY(2,31,2004) (February 31, 2004), the function will return a missing value
and give you an “invalid argument to function” message in the log. The following table gives
examples of how to apply this function, along with relevant comments for each example:

92 The Essential Guide to SAS Dates and Times

Sample Function
Call

SAS Date
Value

Formatted with MMDDYY10.
Format

MDY(9,3,1876)

–30434

09/03/1876

MDY(12,14,15)

20436

12/14/2015

MDY(3,26,1915)

–16352

03/26/1915

MDY(5,22,2033)

26805

05/22/2033

MDY(1,7,2004)

16077

01/07/2004

YYQ(year,qtr); creates a SAS date value from the arguments. Both arguments are
required. year is a numeric variable or constant representing the year, and qtr is a numeric
variable or constant between 1 and 4, representing the quarter of the year. If year is two
digits, the century will be determined by the YEARCUTOFF= system option. This function
returns the date of the first day of the quarter in the given year. The following table gives
examples of how to apply this function, along with relevant comments for each example:

Sample
Function Call

SAS date
Value

Formatted with
MMDDYY10.
Format

YYQ(1995,1)

12784

01/01/1995

YYQ(99,3)

14426

07/01/1999

YEARCUTOFF=1920

YYQ(25,2)

–12693

04/01/1925

YEARCUTOFF=1920, so year
is 1925.

YYQ(2005,2)

16527

07/01/2005

Comment

Chapter 4: Date and Time Functions 93

4.4 Calculating Intervals
Calculating an interval can sometimes be done by using simple math. However, SAS provides
functions to calculate intervals because, in most cases, simple math is only an approximation.
The function is going to be more accurate. For example, one of the mathematical equations for
calculating age is (current date – date of birth)/365.25. This approximation uses the .25 to
account for leap years. In addition, some functions provide more capability, such as the ability
to redefine the starting and ending dates of periods of time such as years. SAS interval
functions are very powerful and can solve a host of problems.

4.4.1 Calculating Elapsed Time with DATDIF() and YRDIF()
DATDIF()
The DATDIF() function calculates the number of days between two dates. The syntax is:

DATDIF(start,end,basis);
Start is the starting date, which can be a date constant, a numeric variable or a SAS
expression. End is the ending date, also a date constant, a numeric variable, or a SAS
expression. Basis is a character constant or variable that tells SAS how to calculate the
difference. It has two possible values:
‘30/360’, which sets each month to 30 days, and the year to 360 days, regardless of
how many days are in each month or year in the span between the two dates. If a day is
at the end of a month (e.g., February 28/29 or March 31) it will be considered as the
30th of the month.
‘ACT/ACT’, which uses the actual number of days in each month and year in the span
between the two dates. This is the default, and it is identical to subtracting start from
end.
If you use a character constant for basis, remember that it will need to be enclosed in quotes,
or you will get an error.

94 The Essential Guide to SAS Dates and Times

Example 4.4.1 The DATDIF Function
DATA _NULL_;
a = DATDIF(‘19JUL2002’d,’19JUL2003’d,’30/360’);
b = DATDIF(‘19JUL2002’d,’19JUL2003’d,’act/act’);
PUT a= / b=;
RUN;

The Log
a=360
b=365

The value of A is 360 because basis is “30/360”, indicating a year of 360 days by
definition. The value of b is 365, because it was calculated with the actual number of days in
the years 2002–2003. If 2003 had been a leap year, then the value would be 366.
YRDIF()
The YRDIF function calculates the number of years between two dates. It is generally more
accurate than using mathematical approximation1. The syntax is:

YRDIF(start,end,basis);
start is the starting date, which can be a date constant, a numeric variable or a SAS
expression. end is the ending date, also a date constant, a numeric variable, or a SAS
expression. basis is a character constant or variable that tells SAS how to calculate the
difference. It has four possible values, as compared with the two possibilities in the DATDIF
function:
‘30/360’, which sets each month to 30 days, and the year to 360 days, regardless of how
many days are in each month or year in the span between the two dates. If a day is at the
end of a month (e.g., February 28/29 or March 31) it will be considered as the 30th of the
month.
‘ACT/ACT’, which uses the actual number of days in each month and year in the span
between the two dates. This is the default.

1

For details about age calculations, see http://support.sas.com/sassamples/quicktips/calcage.html.

Chapter 4: Date and Time Functions 95

‘ACT/360’, which uses the actual number of days between the two dates to calculate the
number of years, but it uses a 360-day year, regardless of how many days are in each year,
so the result is number of days divided by 360.
‘ACT/365’, which uses the actual number of days between the two dates to calculate the
number of years, but uses a 365-day year, regardless of how many days are in each year, so
the result is number of days divided by 365.
The following example shows the effect that each basis definition has on the value that the
YRDIF( ) function returns given the same period of time.
Example 4.4.2: The YRDIF() Function
DATA _NULL_;
A = YRDIF(‘07AUG1963’D,’08MAY2005’D,’30/360’);
B = YRDIF(‘07AUG1963’D,’08MAY2003’D,’ACT/ACT’);
C = YRDIF(‘07AUG1963’D,’08MAY2003’D,’ACT/360’);
D = YRDIF(‘07AUG1963’D,’08MAY2003’D,’ACT/365’);
PUT ‘30 DAY MONTH, 360 DAY YEAR = ‘ A;
PUT ‘ACTUAL DAYS IN MONTH, ACTUAL YEAR = ‘ B;
PUT ‘ACTUAL DAYS IN MONTH, 360 DAY YEAR = ‘ C;
PUT ‘ACTUAL DAYS IN MONTH, 365 DAY YEAR = ‘ D;
RUN;

The Log
30 day
actual
actual
actual

month, 360 day
days in month,
days in month,
days in month,

year = 41.752777778
actual year = 39.750684932
360 day year = 40.330555556
365 day year = 39.778082192

As you can see, all four results are different, and this is due to the way they were calculated. If
each month is 30 days long, and the year is 360 days long, there are 41.75 years between
the two dates. If the actual days in a month are used, but the years are standardized to 360
days, there are 40.33 years between the dates.

96 The Essential Guide to SAS Dates and Times

If the actual days and actual year are used for the calculation, then the value is 39.75. If you
use the actual days, but define the year to be 365 days long, the value is 39.77, a
discrepancy caused by the leap years during that time span. The final example below
illustrates the difference between using the YRDIF() function, the INTNX( ) function (since it
counts elapsed intervals) and mathematical estimation.

4.4.2 The Basics of SAS Intervals
SAS has several interval definitions that are used with dates, times, and datetimes. Although
the standard interval definitions handle many standard time intervals, you have the option of
using interval multipliers and interval shift arguments, which allow you to define intervals.
Multipliers and shift intervals are discussed in detail in Section 5.3. Table 4.4.1 is a list of all
the standard interval definitions and the periods that they describe:
Table 4.4.1 SAS Interval Definitions Used with Dates, Times, and Datetimes

Category

Interval Name

Definition

Default
Starting Point

Date

DAY

Daily intervals

Each day

WEEK

Weekly intervals of seven days

Each Sunday

WEEKDAYdaysW

Daily intervals with Friday-SaturdaySunday counted as the same day
(five-day work week with a SaturdaySunday weekend). days identifies the
individual numbers of the weekend
day(s) by number (1=Sunday ...
7=Saturday). By default, days=“17”,
so the default interval is
WEEKDAY17W.

Each day

(continued on next page)

Chapter 4: Date and Time Functions 97

Table 4.4.1 (continued)

Category
Date

Datetime

Interval Name

Definition

Default
Starting Point

TENDAY

Ten-day intervals (a U.S. automobile
industry convention)

1st, 11th, and 21st
of each month

SEMIMONTH

Half-month intervals

First and sixteenth
of each month

MONTH

Monthly intervals

First of each month

QTR

Quarterly (three-month) intervals

1-Jan
1-Apr
1-Jul
1-Oct

SEMIYEAR

Semi-annual (six-month) intervals

1-Jan
1 Jul

YEAR

Yearly intervals

1-Jan

DTDAY

Daily intervals

Each day

DTWEEK

Weekly intervals of seven days

Each Sunday

DTWEEKDAYdaysW

Daily intervals with Friday-SaturdaySunday counted as the same day
(five-day work week with a SaturdaySunday weekend). days identifies the
individual weekend days by number
(1=Sunday ... 7=Saturday). By
default, days=“17”, so the default
interval is DTWEEKDAY17W.

Each day

DTTENDAY

Ten-day intervals (a U.S. automobile
industry convention)

1st, 11th, and 21st
of each month

DTSEMIMONTH

Half-month intervals

First and sixteenth
of each month

(continued on next page)

98 The Essential Guide to SAS Dates and Times

Table 4.4.1 (continued)

Category

Interval Name

Definition

Default
Starting Point

Datetime

DTMONTH

Monthly intervals

First of each month

DTQTR

Quarterly (three-month) intervals

1-Jan
1-Apr
1-Jul
1-Oct

DTSEMIYEAR

Semiannual (six-month) intervals

1- Jan
1 Jul

DTYEAR

Yearly intervals

1-Jan

DTSECOND

Second intervals

Seconds

DTMINUTE

Minute intervals

Minutes

DTHOUR

Hour intervals

Hours

SECOND

Second intervals

Seconds

MINUTE

Minute intervals

Minutes

HOUR

Hourly intervals

Hours

TIME

4.4.3 Interval Calculation Functions: INTCK and INTNX
The interval calculation functions INTCK( ) and INTNX( ) utilize SAS interval definitions.
INTCK() finds the number of intervals between two given dates, times, or datetimes. In
contrast, INTNX( ) finds the date, time, or datetime that results after a given number of intervals
have been applied to an initial date, time, or datetime value.2

2

As of SAS 9, there are other interval calculation functions available with SAS/ETS and/or SAS High
Performance Forecasting. Releases beyond SAS 9.1 might add some holiday-related functions as well.

Chapter 4: Date and Time Functions 99

INTCK()
The INTCK( ) function counts the number of intervals between two dates, times, or datetimes. It
does so by counting from the beginning of the given interval at start-of-period and the
beginning of the interval at end-of-period. interval is the SAS designation for a period of
time, and can be a character literal or character variable that corresponds to one of the
defined time intervals (see Table 3.4.1.) The syntax of the INTCK function is:

INTCK(interval,start-of-period,end-of-period);
In essence, the INTCK( ) function is counting the number of times that the period interval begins
between start-of-period and end-of-period, inclusive. It does not count the number of complete
intervals between start-of-period and end-of-period. This also means that the count does not
begin with start-of-period, but at the beginning of the first interval after that. The following
sample logs demonstrate how INTCK( ) counts. As an example, take the dates Saturday,
December 31, 2005 and Sunday, January 1, 2006.
The Log
137 DATA _NULL_;
138 v1 = INTCK(‘DAY’,’31dec2005’d,’01jan2006’d);
139 v2 = INTCK(‘WEEK’,’31dec2005’d,’01jan2006’d);
140 v3 = INTCK(‘MONTH’,’31dec2005’d,’01jan2006’d);
141 v4 = INTCK(‘YEAR’,’31dec2005’d,’01jan2006’d);
142 PUT v1= +3 v2= +3 v3= +3 v4= +3;
143 RUN;
v1=1

v2=1

v3=1

v4=1

All of the intervals are equal to 1 even though only one day has passed! January 1, 2006 is
the start of day, week, month, and year intervals. The starting day occurred on December 31,
and the ending day began on January 1. That’s obvious. However, Sunday is the beginning
of the week; therefore, the week for December 31 started on Sunday, December 25. Sunday,
January 1 is the beginning of the next week, so one week has elapsed between the start of the
two weeks containing both dates, and that causes v2 to be equal to 1. The month for
December 31 started on December 1, and the month for January 1, 2006 started on January
1, so one MONTH interval has elapsed between the start of the intervals for the two dates,
and therefore, v3 is 1. Finally, the year for December 31, 2005 started on January 1 of
2005, while the year for January 1, 2006 starts on the same date, which causes v4 to be 1.

100 The Essential Guide to SAS Dates and Times

All of the values are equal to 1 because the INTCK() function is counting the DAY, WEEK,
MONTH, and YEAR interval boundary which occurs because of the number of days, weeks,
months or years that have passed.
To complete the picture of how INTCK() works, let’s look at the effect that the ending date has
on INTCK() .
The Log
144 DATA _NULL_;
145 v5 = INTCK(‘DAY’,’31dec2005’d,’06jan2006’d);
146 v6 = INTCK(‘WEEK’,’31dec2005’d,’06jan2006’d);
147 v7 = INTCK(‘MONTH’,’31dec2005’d,’06jan2006’d);
148 v8 = INTCK(‘YEAR’,’31dec2005’d,’06jan2006’d);
149 PUT v5= +3 v6= +3 v7= +3 v8= +3;
150 RUN;
v5=6

v6=1

v7=1

v8=1

Here you can see that although 6 days have elapsed, still only 1 week, month, and year have
elapsed according to INTCK( ) ! That is because the start of the week, month, and year interval
for January 6, 2006, is still January 1, 2006, and that is what INTCK( ) is counting. Here are
some more examples of the use of INTCK() :
Example 4.4.3 The INTCK Function – the Basics

INTCK(‘DAY’, ‘15jun2003’d,’22jun2003’d) = 7
INTCK(‘WEEK’, ‘01jan2001’d, ‘01jan2002’d) = 52
INTCK(‘DTDAY’, ‘01oct1872:08:00:00’dt ,’20dec1872:18:00:00’dt ) = 80
INTCK(‘MONTH’, ‘05mar1978’d, ‘01may1978’d ) = 2

Chapter 4: Date and Time Functions 101

Example 4.4.4 The INTCK Function – Counting Backwards

INTCK(‘YEAR’, ‘22dec2005’d,’16jul2000’d) =–5

In this example, the from date is after the to date, and therefore, the answer is negative. Since
INTCK() counts interval boundaries, the answer is –5 because it starts counting at the start of
a year. The start of the year for December 22, 2005 is January 1, 2005, so that is where the
count begins. January 1, 2004; January 1, 2003; January 1, 2002; January 1, 2001; and
January 1, 2000 are the beginning dates of the years that it is counting.
Example 4.4.5 The INTCK Function – Counting Weekdays

A) INTCK('WEEKDAY17W','08JAN2006'd,'10JAN2006'd) = 2
B) INTCK('WEEKDAY17W','09JAN2006'd,'10JAN2006'd) = 1
C) INTCK('WEEKDAY17W','06JAN2006'd,'07JAN2006'd) = 0

If you are counting the number of work weekdays that have elapsed, you must be careful to
remember that INTCK( ) counts interval boundaries, and that the starting date is not counted in
the answer. A) above seems perfectly reasonable. You would expect that there would be two
weekdays between Sunday, January 8, 2006 and Tuesday, January 10, 2006. However, you
might think that there are two weekdays in the span Monday, January 9, 2006 to Tuesday,
January 10, 2006, but the INTCK( ) function counts only 1 weekday, because it starts counting
with Tuesday. Why is C) equal to zero then? January 7, 2006 is a Saturday, and since we’ve
defined the weekend days as Saturday and Sunday, the WEEKDAY17W interval does not
begin until Monday, so no interval boundaries have been passed.
The last example for INTCK() illustrates the difference between the three methods that have
been discussed for calculating elapsed years using SAS: the YRDIF() function, the INTCK()
function (because it counts elapsed intervals), and mathematical estimation.

102 The Essential Guide to SAS Dates and Times

Example 4.4.6: The YRDIF() Function as Opposed to Mathematical Estimation
and INTCK()
This uses the same dates, August 7, 1963 and May 8, 2005 for all three methods, but the first
line uses the YRDIF( ) function with “ACT/ACT’, while the mathematical approximation divides
the number of days between the two dates by 365.25. While the discrepancy is minute in this
example, the difference is caused by the fact that the number of leap years in the period (11)
is not divisible by 4, rendering the value 365.25, an approximation. The INTCK function
counts interval boundaries from their beginning, so it is counting the number of January firsts
between January 1, 1963, and January 1, 2003. In effect, unless you were born on January
1, using INTCK( ) to calculate your age will make you old before your time!
DATA _NULL_;
b = YRDIF(‘07aug1963’d,’08may2003’d,’ACT/ACT’);
e = (‘08may2003’d - ‘07aug1963’d)/365.25;
g = INTCK(‘YEAR’,’07aug1963’d,’08may2003’d);
PUT ‘actual days in month, actual year = ‘ b;
PUT ‘math approximation = ‘ e;
PUT ‘Using INTCK = ‘ g;
RUN;

The Log
actual days in month, actual year = 39.750684932
math approximation = 39.750855578
Using INTCK = 40

INTNX()
The INTNX( ) function takes a given SAS date, time, or datetime value, and calculates a new
value based on a given number of intervals. Where INTCK( ) calculates the number of intervals
between any two date, time, or datetime values, INTNX( ) takes the start of the period and
increments it by a number of intervals to give the end-of the period. The syntax is:

INTNX(interval,start-from,number-of-increments, alignment);

Chapter 4: Date and Time Functions 103

interval is one of the SAS intervals defined in Table 3.1, and can be a character literal or
character variable that evaluates to one of the defined intervals. start-from is the starting
date, time, or datetime value, which can be a constant, numeric variable, or a SAS
expression. number-of-increments is an integer constant or a numeric variable that
indicates how many intervals to advance. If it is not an integer, only the integer portion of the
value will be used.
alignment sets the returned date, time, or datetime value according to one of four
predefined settings. The function calculates the dates at the beginning of the interval period,
and then the alignment argument adjusts the result. The values are Beginning or B, Middle or
M, and End or E. The default value for alignment is Beginning. The Sameday or S alignment
operator was added in SAS 9. The Sameday argument cannot be used with the DTQTR,
DTSEMIYEAR, or the DTYEAR intervals, and it has no effect on time values.3
The next series of examples demonstrates various uses and effects of the INTNX() function. The
first example is the default use of the function with each of the date, time, and datetime
intervals, while the second shows what happens when you use a non-integer as the increment
to the function. Example 4.4.9 illustrates the use of the alignment arguments, and Example
4.4.10 shows how to use the alignment arguments to yield specific dates.
Example 4.4.7 The INTNX() Function with Default Alignment
Each of the examples below increments the date, time, or datetime value by 3 of the interval
shown in bold italics. For dates and datetimes, the start date is the same, Thursday, November
2, 2000. The only difference is that datetime intervals (interval names starting with DT) return
datetime values, not dates. The interval values for datetime values are calculated in seconds,
not days. By default, the INTNX( ) function returns the beginning of the interval given. If you
wish to change this, use the alignment argument discussed above.

3

Check releases beyond SAS 9.1 to find whether the SAME operator replaces the SAMEDAY operator.

104 The Essential Guide to SAS Dates and Times

INTNX(‘DAY’,’11/02/2000’d,3) =11/05/2000
INTNX(‘DTDAY’,’02NOV2000:15:00:00’dt,3) =
05NOV2000:00:00:00

The time returned is
midnight of
11/05/2000, not 3 p.m.

INTNX(‘WEEKDAY17W’,’11/02/2000’d,3) = 11/07/2000

The returned date is the
following Tuesday.
Saturday (7) and Sunday
(1) don’t count since they
are defined as the
weekend days.

INTNX(‘DTWEEKDAY17W’,’02NOV2000:15:00:00’dt,3) =
07NOV2000:00:00:00

INTNX(‘WEEK’,’11/02/2000’d,3) =11/19/2000

The value returned is the
Sunday of the week, not
21 calendar days.

INTNX(‘DTWEEK’,’02NOV2000:15:00:00’dt,3) =
19NOV2000:00:00:00

INTNX(‘TENDAY’,’11/02/2000’d,3) = 12/01/2000

The value returned is the
first of the month, 29
calendar days, not 30.
This interval will always
return either the 1st, 11th,
or 21st of the month.

INTNX(‘DTTENDAY’,’02NOV2000:15:00:00’dt,3) =
01DEC2000:00:00:00

INTNX(‘SEMIMONTH’,’11/02/2000’d,3) = 12/16/2000

INTNX(‘DTSEMIMONTH’,’02NOV2000:15:00:00’dt,3) =
16DEC2000:00:00:00

Although November has
30 days, the returned
date is the 16th, not 45
calendar days, which
would be the 17th.

Chapter 4: Date and Time Functions 105

INTNX(‘MONTH’,’11/02/2000’d,3) = 02/01/2001

The date returned is the
beginning of the
following month, not the
same date. To get the
same date, use the “S”
(same day) alignment
argument.

INTNX(‘DTMONTH’,’02NOV2000:15:00:00’dt,3) =
01FEB2001:00:00:00
INTNX(‘QTR’,’11/02/2000’d,3) = 07/01/2001

The first day of the
quarter is returned.

INTNX(‘DTQTR’,’02NOV2000:15:00:00’dt,3) =
01JUL2001:00:00:00

INTNX(‘SEMIYEAR’,’11/02/2000’d,3) = 01/01/2002

The beginning of the 3rd
semi-year after
11/02/2000 is January
1, 2002.

INTNX(‘DTSEMIYEAR’,’02NOV2000:15:00:00’dt,3) =
01JAN2002:00:00:00

INTNX(‘YEAR’,’11/02/2000’d,3) = 01/01/2003

INTNX(‘DTYEAR’,’02NOV2000:15:00:00’dt,3) =
01JAN2003:00:00:00
INTNX(‘SECOND’,’8:00:00 AM’t,3) = 8:00:03 AM
INTNX(‘MINUTE’,’8:00:00 AM’t,3) = 8:03:00 AM
INTNX(‘HOUR’,’8:00:00 AM’t,3) = 11:00:00 AM

The beginning of the 3rd
year after 11/02/2000
is January 1, 2003.

106 The Essential Guide to SAS Dates and Times

Example 4.4.8 The INTNX() Function – Using Non-Integer Increments

INTNX(‘HOUR ‘, ‘16:45’t ,2.5 ) = 18:00:00

When number-of-increments is not an integer, SAS will take the integer part as the value. In
this case, 2.5 becomes 2. The beginning of the first hour increment is 17:00, and the second
is 18:00. Since alignment is the default value of B or beginning, that sets the answer to the
beginning of the hour, which gives the result of 18:00.
Example 4.4.9 The INTNX() Function with Alignment Arguments

INTNX(‘WEEK’,’11/02/2000’d,3,’B’) =11/19/2000

Beginning of the week.

INTNX(‘WEEK ‘,’11/02/2000’d,3,’M ‘)=11/22/2000

Middle of the interval.

INTNX(‘WEEK ‘,’11/02/2000’d,3,’S’)=11/23/2000

Same day, so the interval ends on the
same day of the week (Wednesday),
leaving the duration at 21 days.

Example 4.4.10 The INTNX() Function with Alignment Arguments to Give
Specific Dates

Set the date to the beginning of
the week.

INTNX(‘WEEK’,’27JUL2002’d,0,’B’) = July 21, 2002

Advance to the start of the 3rd
semi-month period.

INTNX(‘SEMIMONTH’,’01MAY1998’d,3,’B’) = June 16, 1998

Advance to the end of the
month.

INTNX(‘MONTH’,’05MAR2005’d,1,’E’) = April 30, 2005

Advance to the end of the
quarter after next.

INTNX(‘QTR’,’06NOV1996’d,2,’E’) = June 30, 1997

CHAPTER 5

Deeper into Dates and Times with SAS
5.1 Macro Variables and Dates............................................................................108
5.1.1 Automatic Macro Variables ..................................................................108
5.1.2 Putting Dates into Titles.........................................................................109
5.1.3 Using %SYSFUNC() to Create Dates, Times, and Datetimes in Macro
Variables ...........................................................................................110
5.1.4 Using CALL SYMPUT() and SYMGET() with Dates, Times, and Datetimes ....111
5.2 Shifting SAS Date and Time Intervals ...............................................................113
5.3 Graphing Dates ............................................................................................122
5.4 The Basics of PROC EXPAND .........................................................................127
5.4.1 Capabilities of PROC EXPAND .............................................................127
5.4.2 Using PROC EXPAND to Convert to a Higher Frequency..........................129
5.4.3 Using PROC EXPAND to Convert to a Lower Frequency ...........................130
5.4.4 Using PROC EXPAND to Interpolate Missing Values ...............................132
5.4.5 The OBSERVED= Option for the CONVERT Statement in PROC EXPAND...133
5.5 International Date, Time, and Datetime Formats and Informats ............................136
5.5.1 “EUR” Formats and Informats ................................................................137
5.5.2 “NL” Formats ......................................................................................140
5.5.3 Specific Language Date Formats and Informats .......................................143
5.6 Other Software and Their Dates (Excel, Oracle, DB2)........................................144

108

The Essential Guide to SAS Dates and Times

5.1 Macro Variables and Dates
There is a high potential for confusion when it comes to the subject of macro variables and
dates. Although you have access to dates and times in the SAS macro language with the
automatic macro variables &SYSDATE, &SYSDATE9, &SYSDAY, and &SYSTIME, the display
of these values is fixed, and therefore they do not give you the power of SAS formats, or of
SAS date and time functions.

5.1.1 Automatic Macro Variables
None of these automatic macro variables may be assigned values with %LET or CALL
SYMPUT( ) , or by any other means. They are read-only, and work by reading the operating
system clock when a SAS session is started. This means that they do not change within a given
SAS session.
&SYSDATE This automatic macro variable cannot be modified, and displays the system date
as a SAS date value formatted with the DATE7. format. If the date according to the operating
system when the SAS session starts is July 17, 2004, then &SYSDATE would be equal to
“17JUL04”. This example shows the value of &SYSDATE when the date is October 4, 2002:
/* The computer’s date is October 4, 2002 */
3 %PUT &SYSDATE;
04OCT02

&SYSDATE9 This automatic macro variable is identical to &SYSDATE, except that it formats
the system date with the DATE9. format, and is therefore Y2K-compliant. If the operating
system date is November 22, 2005, then &SYSDATE9 would be equal to “22NOV2005”.
This example shows the value of &SYSDATE9 when the date is October 4, 2002:
/* The computer’s date is October 4, 2002 */
6 %PUT &SYSDATE9;
04OCT2002

&SYSDAY This automatic variable displays in English the name of the day that the SAS
session began (according to the operating system). If you started a SAS job or session on
Wednesday, February 11, 1998, &SYSDAY would be equal to “Wednesday”. This example
shows the value of &SYSDAY when the date is Friday, October 4, 2002:

Chapter 5: Deeper into Dates and Times with SAS

109

/* THE COMPUTER’S DATE IS OCTOBER 4, 2002 */
9 %PUT &SYSDAY;
Friday

&SYSTIME This automatic variable displays the system time (according to the operating
system) in TIME5. format. If the system time is 3:36 PM when you start SAS, then &SYSTIME
would be equal to “15:36”. This example shows the value of &SYSTIME when the time is
10:36 PM:
/* THE CURRENT TIME IS 10:36 PM */
12 %PUT &SYSTIME;
22:36

5.1.2 Putting Dates into Titles
One of the prime uses of dates in macro variables is for custom titles and footnotes. To use a
macro variable in a title, you just need to enclose the TITLE or FOOTNOTE statement that
contains the macro variable with double quotes like this:
TITLE “This is how to put a macro variable in a title: Today’s
Date is &SYSDATE9”;
To see this in context, look at the following program:
TITLE “This is how to put a macro variable in a title: Today’s Date is
&SYSDATE9”;
ODS RTF FILE=“examples\title.rtf”;
PROC PRINT DATA=sashelp.company (OBS=5);
ID job1;
VAR depthead;
RUN;
ODS RTF CLOSE;

110

The Essential Guide to SAS Dates and Times

Here is the resulting output:

This is how to put a macro variable in a title: Today’s Date is 21JUN2005
JOB1

DEPTHEAD

MANAGER

1

ASSISTANT

2

ACCOUNTANT

2

MANAGER

1

ADMIN

2

While the automatic macro variables &SYSDATE, &SYSDATE9, &SYSDAY, and &SYSTIME
may give you the information you need, their formats are fixed and cannot be changed. Given
the multiple ways that dates, times, and datetimes can be displayed, it would be good if you
could use the formats and functions to get the display of dates and times that you want in your
titles.

5.1.3 Using %SYSFUNC() to Create Dates, Times, and Datetimes in Macro Variables
Many of the date and time functions, as well as formats, are available in the SAS macro
language through the %QSYSFUNC() and %SYSFUNC( ) macro functions. When you are
using one of these macro functions with dates and times, it has two arguments: the first is the
date, time, or datetime function you wish to use. The second argument is optional, but it is the
format that should be applied to the result.
Example 5.1.1 Date Functions with %QSYSFUNC()
This example puts the formatted value of today’s date into the macro variable &date, and
demonstrates the difference between unformatted and formatted dates in macro variables. The
date value in &RAWDATE is stored in macro space as a text string, and will need to be
converted if you want to use it for any calculations. &DATE shows that the WORDDATE.
format right-justifies the date display. So, in order to remove the leading spaces, the %LEFT()
macro function is used and the result is stored in the macro variable &DATEJ.

Chapter 5: Deeper into Dates and Times with SAS

111

7
%LET
8
%LET
9
%LET
10
%PUT
16592
11
%PUT

rawdate=%QSYSFUNC(DATE());
date=%QSYSFUNC(DATE(),WORDDATE32.);
datej=%LEFT(%QSYSFUNC(DATE(),WORDDATE32.));
&rawdate;
/* SAS Date Value */
&date;
June 5, 2005 /* Formatted */
12
%PUT &datej;
June 5, 2005 /* Formatted and left-justified */

Now you can use the result in a title or footnote.
Example 5.1.2 Taking a Macro Text String and Turning It into a SAS Date
Value
This example takes the macro value from the automatic macro variable &SYDATE9 and will
get the SAS date value from it. The PUTN( ) function is used here instead of the PUT( ) function
because the format is determined during execution of the statement.
13 %LET DATEVAL = %SYSFUNC(PUTN(“&SYSDATE9”D,5.)); /* USE PUTN(), NOT
PUT()! */
14 %PUT sysdate is &sysdate9;
sysdate is 05JUN2005
15 %PUT The SAS date value is: &dateval;
The SAS date value is: 16592

5.1.4 Using CALL SYMPUT() and SYMGET() with Dates, Times, and Datetimes
The CALL SYMPUT( ) and SYMGET() functions are also used to communicate between the
DATA step and the macro world. CALL SYMPUT( ) takes a value and stores it in macro space
from within a DATA step, while SYMGET() takes a macro variable and allows you to use it in
a DATA step. The difference between run-time and compile time is very important. You cannot
use a %LET statement to store macro values that are defined during execution of a DATA step.
You also cannot use a macro variable reference (with an ampersand (&)) in the same DATA
step where the macro variable is created with CALL SYMPUT( ) . The next example uses what
was discussed in Sections 5.1.2 and 5.1.3 to show how you can obtain a date value from a
SAS data set and then put it in a macro variable to use in a title.

112

The Essential Guide to SAS Dates and Times

Example 5.1.3 Using CALL SYMPUT to Create a Macro Variable Containing a
Formatted SAS Date
This example calculates the most recent date in a given variable from a dataset, and then
creates a macro variable containing the formatted value to be used in a title.
/* Get the maximum date in the variable */
PROC MEANS DATA=BOOK.PMDATA MAX NOPRINT;
VAR LAST_DATE;
OUTPUT OUT=TMP MAX=MAX;
RUN;
/*Transfer it to a macro variable using CALL SYMPUT() */
DATA _NULL_;
SET TMP;
CALL SYMPUT(‘ASOF’,LEFT(PUT(MAX,WORDDATE32.)));
RUN;
OPTIONS NODATE;

/* REMOVE AUTOMATIC SYSTEM DATE ON PAGE */

/*CREATE TITLE with macro variable &asof */
TITLE “PROJECT DATA LAST UPDATED ON &ASOF”;
ODS RTF FILE=“EXAMPLES\SYMPUT.RTF”;
PROC PRINT DATA=BOOK.PMDATA LABEL;
VAR LAST_DATE;
RUN;

This is the resulting report:

Project Data Last Updated on June 1, 2005
Obs Date last modified
10/29/2003
1
08/13/2003
2
10/31/2003
3
.
4
06/01/2005
5
03/30/2005
6
06/01/2005
7
06/01/2005
8
07/21/1997
9
07/23/1997
10
12/03/2001
11

Chapter 5: Deeper into Dates and Times with SAS

113

Since the maximum date in the data is June 1, 2005 (highlighted in bold italics for the
example,) that is the value that is formatted and passed to the CALL SYMPUT function as the
macro variable &asof.

5.2 Shifting SAS Date and Time Intervals
The interval function INTCK(interval,start-of-period,end-of-period) counts the number of
intervals between two given SAS dates, times, or datetimes, while the function
INTNX(interval,start-from,number-of-increments,alignment) advances a given date, time, or
datetime by a specified number of intervals. Both functions use the standard SAS interval
definitions (see Table 5.2.1). However, the INTCK( ) function counts at the start point of a
given interval, while the INTNX( ) function advances to the beginning of the given interval. The
alignment argument available with INTNX( ) will adjust the result to the middle, end, or—if
you’re using Version 9—same day of the interval. Nonetheless, the intervals are still measured
from their starting point, and the adjustment is only applied after INTNX( ) has moved the
specified number of intervals.
This leads to problems when your definition of an interval doesn’t exactly match the standard
SAS definition of that same interval. For example, the standard SAS definition of year has the
first day of the year defined as starting January 1. What happens if your fiscal year starts on
July 1, and that is how you wish to measure your year? What if your semi-month period is truly
14 days long?
Shift operators and interval multipliers allow you to do this. You have the ability to define the
start of an interval definition by adding a shift indicator to it. The shift indicator defines the
number of shift points to move the start of the interval. The table below shows the SAS interval
name and what the shift increment period is.

114

The Essential Guide to SAS Dates and Times

Table 5.2.1 SAS Intervals and their Shift Points
CATEGORY
DATE

INTERVAL

DEFINITION

SHIFT POINT

DAY

Daily intervals

Days

WEEK

Weekly intervals of seven days

Days

WEEKDAY

Daily intervals with Friday-Saturday-Sunday
counted as the same day. days identifies the
individual weekend days by number
(1=Sunday ... 7=Saturday). By default,
days=“17”, so the default interval is
WEEKDAY17W.

Days

TENDAY

Ten-day intervals

Ten day periods

SEMIMONTH

Half-month intervals

Semimonthly
periods

MONTH

Monthly intervals

Months

QTR

Quarterly (three-month) intervals

Months

SEMIYEAR

Semi-annual (six-month) intervals

Months

YEAR

Yearly intervals

Months

(continued on next page)

Chapter 5: Deeper into Dates and Times with SAS

115

Table 5.2.1 (continued)
CATEGORY

INTERVAL

DATETIME

DTDAY

Daily intervals

Days

DTWEEK

Weekly intervals of seven days

Days

DTWEEKDAY

Daily intervals with Friday-SaturdaySunday counted as the same day.
days identifies the individual weekend
days by number (1=Sunday ...
7=Saturday). By default, days=“17”,
so the default interval is
DTWEEKDAY17W.

Days

DTTENDAY

Ten-day intervals

Ten day periods

DTSEMIMONTH

Half-month intervals

Semimonthly
periods

DTMONTH

Monthly intervals

Months

DTQTR

Quarterly (three-month) intervals

Months

DTSEMIYEAR

Semiannual (six-month) intervals

Months

DTYEAR

Yearly intervals

Months

DTSECOND

Second intervals

Seconds

DTMINUTE

Minute intervals

Minutes

DTHOUR

Hour intervals

Hours

SECOND

Second intervals

Seconds

MINUTE

Minute intervals

Minutes

HOUR

Hourly intervals

Hours

TIME

DEFINITION

SHIFT POINT

116

The Essential Guide to SAS Dates and Times

For our first example, let’s use the standard case of a fiscal year that starts on July 1. To
measure a year interval in those terms, you would have to move the start of the year by seven
months. The start point is always included in the count of months to shift. The shift value is
added to the interval name by appending it with a decimal point. Therefore, in order to
advance the start of the YEAR interval seven months to July 1, you would use the interval name
“YEAR.7”, as illustrated by the following:
Example 5.2.1 Moving the Start of a Year Interval from January 1 to July 1
DATA _NULL_;
a = INTCK(‘YEAR’,’01jan2003’d,’06jul2004’d);
b = INTCK(‘YEAR.7’,’01jan2003’d,’06jul2004’d);
PUT ‘INTCK with YEAR interval=‘ a + 3 ‘INTCK with YEAR.7 interval=‘ b;
RUN;

The Log
6
7
8
9
10

DATA _NULL_;
a = INTCK(‘YEAR’,’01jan2003’d,’06jul2004’d);
b = INTCK(‘YEAR.7’,’01jan2003’d,’06jul2004’d);
PUT ‘INTCK with YEAR interval=‘ a +3 ‘INTCK with YEAR.7 interval=‘ b;
RUN;

INTCK with YEAR interval=1

INTCK with YEAR.7 interval=2

Since INTCK( ) counts the start of interval boundaries, when the interval is “YEAR”, it is
measuring from January 1, 2003 until January 1, 2004 (the start of the year containing July 6,
2004). When the interval is “YEAR.7”, you have shifted the beginning of the YEAR interval by
7 months, which declares that the year starts on July 1. In the example above, that shift causes
the measurement to commence on July 1, 2002 (the start of the year containing January 1,
2003) and end on July 1, 2004, which is the start of the year containing July 6, 2004. That is
why the value returned is 2, not 1.
While shift operators allow you to move the starting point of any given SAS interval, an
interval multiplier allows you to define the length of your own intervals. You define a custom
interval by applying a multiplier value to an interval. For example, if you want to measure
biweekly (14-day) periods, you would take the WEEK interval, and multiply it by 2. This
makes your interval name “WEEK2”, and it measures 14-day periods starting on Sunday.
Example 5.2.2 demonstrates the creation and use of a custom interval, by using a multiplier of
2 for the WEEK interval. It also illustrates some of the features of custom intervals.

Chapter 5: Deeper into Dates and Times with SAS

117

Example 5.2.2 Using an Interval Multiplier to Create a Custom Interval
DATA _NULL_;
a = INTNX(‘WEEK’,’08feb2004’d,2);
b = INTNX(‘WEEK2’,’08feb2004’d,2);
PUT ‘INTNX with WEEK interval=‘ a weekdate32.;
PUT ‘INTNX with WEEK2 interval=‘ b weekdate32.;
RUN;

The Log
68
69
70
71
72
73

DATA _NULL_;
a = INTNX(‘WEEK’,’08feb2004’d,2);
b = INTNX(‘WEEK2’,’08feb2004’d,2);
PUT ‘INTNX with WEEK interval=‘ a weekdate32.;
PUT ‘INTNX with WEEK2 interval=‘ b weekdate32.;
RUN;

INTNX with WEEK interval=
INTNX with WEEK2 interval=

Sunday, February 22, 2004
Sunday, March 7, 2004

In the above example, the start of the week interval two weeks from February 8 is February
22, so it makes sense that the start of the second biweekly period from February 8 is March 7.
This is not as simple as it seems. When using SAS intervals, you must always keep in mind
that intervals are always measured from the beginning of the starting interval to the beginning
of the ending interval. This is independent of the starting and ending dates that you supply.
Let’s move the starting date in Example 5.5.2 backward by one week to February 1, 2004.
The Log
1
2
3
4
5
6

DATA _NULL_;
a = INTNX(‘WEEK’,’01feb2004’d,2);
b = INTNX(‘WEEK2’,’01feb2004’d,2);
PUT ‘INTNX with WEEK interval=‘ a weekdate32.;
PUT ‘INTNX with WEEK2 interval=‘ b weekdate32.;
RUN;

INTNX with WEEK interval=
INTNX with WEEK2 interval=

Sunday, February 15, 2004
Sunday, February 22, 2004

118

The Essential Guide to SAS Dates and Times

Advancing by two WEEKS (line 2) is still a difference of 14 days, as expected. But what
happened in line 3? Shouldn’t you get 28 days instead of 21? No, because the start of the
WEEK2 interval containing February 1, 2004 is January 25, 2004, and that is where the
INTNX( ) function begins its count. Here is a sample program to produce the starting dates of
the intervals:
DATA tricky;
DO intervals= 0 TO 5;
b = INTNX(‘WEEK2’,’01jan2004’d,intervals);
OUTPUT;
END;
RUN;
PROC PRINT DATA=tricky LABEL;
ID interval;
VAR b;
FORMAT b weekdate32.;
LABEL interval=“Number of WEEK2 intervals from January 1, 2004”
b=“Starting Date of Interval”
;
RUN;

The resulting table (below) shows the starting dates for the first five WEEK2 intervals of 2004.
If the date(s) supplied fall between the starting dates of any two boundaries, the interval count
(or incrementing) will commence from the starting date of the previous interval.
Number of WEEK2 intervals
from January 1, 2004
Starting Date of Interval
0

Sunday, December 28, 2003

1

Sunday, January 11, 2004

2

Sunday, January 25, 2004

3

Sunday, February 8, 2004

4

Sunday, February 22, 2004

5

Sunday, March 7, 2004

How does SAS determine what the starting date of a given interval is if you use a multiplier? It
takes the multiplied interval you’ve created and starts counting beginning with January 1,
1960. This is true for all multiplied intervals except multiplied WEEK intervals. Multiplied
WEEK intervals are counted starting from Sunday, December 27, 1959, because weeks are
defined as starting on Sundays, and January 1, 1960 was a Friday.

Chapter 5: Deeper into Dates and Times with SAS

119

You may also use a multiplier and a shift indicator together if needed. Interval multipliers are
directly appended to the interval name (e.g., WEEK2), and shift indicators are appended to
the interval name with a leading decimal point (e.g., WEEK.5). To use both the multiplier and
shift operator, you first append the multiplier to the interval name to create a new interval
name (e.g., WEEK2), and then you append the shift indicator to the interval name. Given a
multiplier of 2, and a shift of 5, the interval name becomes “WEEK2.5”.
To demonstrate, let’s expand on the example used in 5.2.2. What if you wanted your
biweekly periods to start on January 1, 2004? January 1, 2004 was a Thursday, so you want
to move the starting date to the fifth day of the week (Sunday=1, therefore, Thursday=5.) Now
we’ll generate the same table as in Example 5.2.2, using a shift indicator of 5 days in
addition to the biweekly interval of WEEK2.
Example 5.2.3 Using Both an Interval Multiplier and Shift Operator to Create
a Custom Interval
DATA tricky;
DO interval= 0 TO 5;
b = INTNX(‘WEEK2.5’,’01jan2004’d,interval);
OUTPUT;
END;
RUN;
PROC PRINT DATA=tricky LABEL;
ID interval;
VAR b;
FORMAT b weekdate32.;
LABEL interval=“Number of WEEK2.5 intervals from January 1, 2004”
b=“Starting Date of Interval”
;
RUN;

120

The Essential Guide to SAS Dates and Times

Here’s the resulting output:
Number of WEEK2.5 intervals
Starting Date of Interval
from January 1, 2004
0

Thursday, January 1, 2004

1

Thursday, January 15, 2004

2

Thursday, January 29, 2004

3

Thursday, February 12, 2004

4

Thursday, February 26, 2004

5

Thursday, March 11, 2004

When you use a multiplier, you also have the ability to define your shifts within the entire
interval created by the multiplier. As an example, let’s create a decade interval by using
YEAR10 as the interval. Remember that intervals start at the beginning of the boundary, so the
decades would start at the beginning of the first year of the decade. What can you do if you
want to define the decade as starting in May of the middle year in the decade (e.g., May of
1955 as opposed to January of 1950?)
To shift intervals across years, you need to use the first nested interval within the YEAR interval,
which is MONTH. So you would use (number of years to shift*12) to calculate the number of
months you need to shift. If you wanted to shift 5 years, you would use 5*12=60. Add 5 to
that, which shifts the starting month from January to May, and your interval definition is now
YEAR10.65. That would be decades starting in May of years that end in 5. The code below
shows the effect of moving the interval by 65 months.
DATA tricky;
DO interval= 0 TO 5;
b = INTNX(‘YEAR10’,’01sep1950’d,interval);
c = INTNX(‘YEAR10.65’,’01sep1950’d,interval);
OUTPUT;
END;
RUN;

Chapter 5: Deeper into Dates and Times with SAS

121

PROC PRINT DATA=tricky LABEL;
ID interval;
VAR b c;
FORMAT b c weekdate32.;
LABEL interval=“Number of intervals from January 1, 1950”
b=“Starting Date of YEAR10 Interval”
c=“Starting Date of YEAR10.65 Interval”
;
RUN;

For this table, we show the unshifted result alongside the shifted result for comparison:
Number of intervals
from January 1, 1950

Starting Date of
YEAR10 Interval

Starting Date of
YEAR10.65 Interval

0

Sunday, January 1, 1950

Tuesday, May 1, 1945

1

Friday, January 1, 1960

Sunday, May 1, 1955

2

Thursday, January 1, 1970

Saturday, May 1, 1965

3

Tuesday, January 1, 1980

Thursday, May 1, 1975

4

Monday, January 1, 1990

Wednesday, May 1, 1985

5

Saturday, January 1, 2000

Monday, May 1, 1995

The first thing to note is that even though the date we specified is September 1, the starting
date of the interval is January 1, because that is the start of the YEAR interval. In the second
column, you can see that the interval has been shifted. Even though the starting date of the
YEAR10. interval is January 1, 1950, the shifted interval itself starts on Tuesday, May 1, 1945
(italics), not May 1, 1955. Why? Because it is the start of the interval that contains January 1,
1950.
The most important thing to remember about using intervals, multipliers, and shift operators is
that all intervals, no matter how they are defined, are measured from their beginning
regardless of what date(s) you provide when you are using them. The alignment arguments
‘B’, ‘M’, ’E’, and ‘S’ for the INTNX() function do not adjust the date until after the function has
executed and calculated its start-of-interval result (also remember that these alignment
arguments only work with the INTNX( ) function).

122

The Essential Guide to SAS Dates and Times

No matter what, you may use the interval multipliers and shift operators to move the starting
point of an interval, and you may use them anywhere that you can use a date, time, or
datetime interval.

5.3 Graphing Dates
When you use dates, times, or datetime values in SAS/GRAPH, you have to remember that
they are numbers. This has a large impact on the axes and labeling. Graphing a result over a
period of time without using formats or intervals will usually result in a graph that is not clear
or well-defined. Example 5.3.1 demonstrates how the use of formats, interval multipliers, and
shift operators can be used to make your graphs involving dates self-explanatory.
Example 5.3.1 Johnny’s Savings Account
When Johnny turned 10 years old on September 1, 1975, he took all the money he had in his
piggybank and deposited it into a bank account that paid 4.5% interest annually,
compounded daily. He made a promise to add two dollars at the end of each week from any
money that he earned, and that he would take the money out when he reached the ripe old
age of 40. Johnny thought he might have $1,000 by then. He kept that promise, so let’s look
at Johnny’s earnings from the time he was 10 until he was 40 using the following program:
TITLE “Johnny’s 40th Birthday Fund”;
PROC GPLOT DATA=book.graph1;
PLOT fund*date / VREF=5000 LV=1 CV=blue;
RUN;

Chapter 5: Deeper into Dates and Times with SAS

123

Here is the resulting output:

Johnny's 40th Birthday Fund
fund
$8,000.00
$7,000.00
$6,000.00
$5,000.00
$4,000.00
$3,000.00
$2,000.00
$1,000.00
$0.00
4000

6000

8000

10000

12000

14000

16000

18000

date

That’s not very helpful. We can see that he started around 6000, and he turned 40
somewhere around 17000. What does that mean? This is easy enough to fix. Don’t we just
need to add a format to the dates like this?
TITLE “Johnny’s 40th Birthday Fund”;
PROC GPLOT DATA=book.graph1;
PLOT fund*date / VREF=5000 LV=1 CV=blue;
FORMAT date mmddyy10.; /* Add FORMAT statement */
RUN;

124

The Essential Guide to SAS Dates and Times

Here is the new output:

Johnny's 40th Birthday Fund
fund
$8,000.00
$7,000.00
$6,000.00
$5,000.00
$4,000.00
$3,000.00
$2,000.00
$1,000.00
$0.00
01/01/1970

01/01/1980

01/01/1990

01/01/2000

01/01/2010

date

What has happened here is that SAS picked the boundaries and figured out major and minor
tick marks. In this example, it has selected major intervals at decade boundaries, and minor
ones at year boundaries. That’s not a bad choice for this example, but SAS/GRAPH doesn’t
always make such a good choice when picking the boundaries of an axis. Can’t you define
the horizontal axis yourself?
Sure you can! Johnny’s birth date is in September, so it would make more sense to chart his
progress at his birthdays, and restrict the span of the horizontal axis to the period he’s
contributing. Let’s shift the interval by nine months to fix the starting date and try this code:
TITLE “Johnny’s 40th Birthday Fund”;
PROC GPLOT DATA=book.graph1;
PLOT fund*date / VREF=5000 LV=1 CV=blue
HAXIS=‘01SEP1975’d TO ‘01SEP2005’d by YEAR.9;
FORMAT date mmddyy10.;
RUN;

Chapter 5: Deeper into Dates and Times with SAS

125

Here is the resulting output:

Johnny's 40th Birthday Fund
fund
$10,000.00
$0.00
0
9
/
0
1
/
1
9
7
5

0
9
/
0
1
/
1
9
7
6

0
9
/
0
1
/
1
9
7
7

0
9
/
0
1
/
1
9
7
8

0
9
/
0
1
/
1
9
7
9

0
9
/
0
1
/
1
9
8
0

0
9
/
0
1
/
1
9
8
1

0
9
/
0
1
/
1
9
8
2

0
9
/
0
1
/
1
9
8
3

0
9
/
0
1
/
1
9
8
4

0
9
/
0
1
/
1
9
8
5

0
9
/
0
1
/
1
9
8
6

0
9
/
0
1
/
1
9
8
7

0
9
/
0
1
/
1
9
8
8

0
9
/
0
1
/
1
9
8
9

0
9
/
0
1
/
1
9
9
0

0
9
/
0
1
/
1
9
9
1

0
9
/
0
1
/
1
9
9
2

0
9
/
0
1
/
1
9
9
3

0
9
/
0
1
/
1
9
9
4

0
9
/
0
1
/
1
9
9
5

0
9
/
0
1
/
1
9
9
6

0
9
/
0
1
/
1
9
9
7

0
9
/
0
1
/
1
9
9
8

0
9
/
0
1
/
1
9
9
9

0
9
/
0
1
/
2
0
0
0

0
9
/
0
1
/
2
0
0
1

0
9
/
0
1
/
2
0
0
2

0
9
/
0
1
/
2
0
0
3

0
9
/
0
1
/
2
0
0
4

0
9
/
0
1
/
2
0
0
5

date

What happened here? Well, since we defined the horizontal axis as having tick marks every
year, SAS accommodated our request. It was even thoughtful enough to turn the labels
vertically to make sure that they all fit. Unfortunately, that left very little space for the graph
itself, because SAS thinks the labels are more important than the graph. We need better
spacing on our horizontal axis.
Since decades seemed to work well, let’s use those as our intervals, but we want to start on
Johnny’s tenth birthday, and define the major horizontal axis points at September 1, 1975,
September 1, 1985, September 1, 1995, and September 1, 2005. An interval multiplier of
10 will create the decade interval, and a shift operator of 69 (60 (months in 5 years) plus 9
(months from January to September)) will move the starting date of the ten-year interval to
September 1975 so that it matches the starting point of the horizontal axis. Note that the only
change from the previous version is in the interval definition.

126

The Essential Guide to SAS Dates and Times

TITLE “Johnny’s 40th Birthday Fund”;
PROC GPLOT DATA=book.graph1;
PLOT fund*date / VREF=5000 LV=1 CV=blue
HAXIS=‘01SEP1975’d TO ‘01SEP2005’d BY YEAR10.69; /* Define X
axis with an
interval */
FORMAT date mmddyy10.;
RUN;

Here is the resulting output:

Johnny's 40th Birthday Fund
fund
$8,000.00
$7,000.00
$6,000.00
$5,000.00
$4,000.00
$3,000.00
$2,000.00
$1,000.00
$0.00
09/01/1975

09/01/1985

09/01/1995

09/01/2005

date

Now that’s what we wanted. This demonstrates that you have all of the interval types, as well
as their multipliers and shift operators, available when you are defining axes that involve date,
time, and datetime values in SAS/GRAPH. It makes defining the exact scope of the graph
much easier, not to mention comprehending what you’ve graphed.

Chapter 5: Deeper into Dates and Times with SAS

127

5.4 The Basics of PROC EXPAND
The EXPAND procedure is a part of SAS/ETS, which is used with time series data. It creates a
SAS data set, and does not routinely produce printed output. With Version 9 of SAS, you can
use ODS for Statistical Graphics to produce output from PROC EXPAND, but it is an
experimental product.

5.4.1 Capabilities of PROC EXPAND
It will change the sampling frequency of the data that you have and convert it to a different
one. It can interpolate values in time series data, for example, when you have quarterly data
that you need to report or analyze on a monthly basis. It can perform the reverse operation,
that is, to aggregate (collapse) data from a higher sampling frequency to a lower one, such as
taking monthly data and turning it into quarterly data. PROC EXPAND can interpolate missing
values even if you aren’t changing the sampling frequency. It also provides for extensive data
transformations, and performs all of these functions without a lot of DATA step programming.
The SAS/ETS documentation provides detail on the procedure, its statements, and the options
for those statements.
PROC EXPAND uses SAS interval definitions. This includes shift operators and interval
multipliers. For a detailed explanation of shift operators and interval multipliers, see
Section 5.2. When you use these interval definitions (plus any shift and/or multipliers,) PROC
EXPAND will automatically adjust for any calendar effects (leap years, varying number of
days in a month). As with anything that uses these interval definitions, all measurements and
calculations are considered to be at the beginning of the interval(s) specified. It is possible to
change that definition with options in one of the PROC EXPAND statements, and those are
discussed in Section 5.4.5.
Table 5.4.1 PROC EXPAND Sample Data
The following data set will be used for the examples in this section. This is light rail ridership
data obtained from the American Public Transportation Association for the years 2003 and
2004, and is used with their permission. The values for October and November of 2003 have
been removed to demonstrate some of the capabilities of PROC EXPAND.

128

The Essential Guide to SAS Dates and Times

date

Riders
(thousands)

JAN2003

2679.9

FEB2003

2421.9

MAR2003

2704.6

APR2003

2778.3

MAY2003

2718.6

JUN2003

2618.2

JUL2003

2999.0

AUG2003

3504.7

SEP2003

3329.4

OCT2003

.

NOV2003

.

DEC2003

2888.6

JAN2004

3132.9

FEB2004

2814.3

MAR2004

3067.3

APR2004

2928.8

MAY2004

2958.3

JUN2004

2966.3

JUL2004

3000.8

AUG2004

3071.2

SEP2004

2958.9

OCT2004

2992.8

NOV2004

3017.5

DEC2004

3038.4

Chapter 5: Deeper into Dates and Times with SAS

129

5.4.2 Using PROC EXPAND to Convert to a Higher Frequency
You can use PROC EXPAND to convert data from a lower sampling frequency to a higher
sampling frequency (e.g., converting monthly data to daily or weekly data.) It does so by
interpolation, and the syntax to convert to a higher sampling frequency is as follows:
1
2
3
4

PROC EXPAND DATA=book.month OUT=seven_days FROM=MONTH TO=WEEK;
ID date;
CONVERT riders;
RUN;

The PROC EXPAND statement in line 1 specifies the output data set (“seven_days”), and
explains how the data in BOOK.MONTH should be converted, from MONTH intervals to
WEEK intervals. The ID statement in line 2 indicates the variable that identifies the time of
each record.
You will usually use an ID statement with PROC EXPAND; otherwise, SAS will create an ID
variable for the input records, and it will use the starting point of January 1, 1960, which may
not be what you want. The CONVERT statement identifies the variable(s) to convert. You may
also rename the variable(s) being converted in the output data set like this: CONVERT
input-var=output-var;
Here are the first eight observations from the data set
SEVEN_DAYS produced by the above code:

date

Riders
(thousands)

29DEC2002

2770.23

05JAN2003

2573.57

12JAN2003

2449.76

19JAN2003

2393.52

26JAN2003

2391.24

02FEB2003

2429.29

09FEB2003

2494.03

16FEB2003

2571.86

130

The Essential Guide to SAS Dates and Times

5.4.3 Using PROC EXPAND to Convert to a Lower Frequency
You can convert data to a lower frequency with PROC EXPAND in two ways: first, you can
use the same syntax as with converting to a higher sampling frequency, except that the TO=
interval would be of a lower sampling frequency. When you convert your data this way,
PROC EXPAND performs interpolation for missing values using a curve fitting method, and
allows conversion between intervals that aren’t nested. A nested interval is one that fits wholly
inside of another interval (e.g., days nest within weeks, because there are exactly seven days
in a week, but weeks do not nest within months, because most months have partial weeks).
The following program will interpolate any missing values in our data:
PROC EXPAND DATA=book.month OUT=quarterly FROM=MONTH TO=QTR;
ID date;
CONVERT riders;
RUN;

Obs

date

Riders (thousands)
After Interpolation

Original Values
From BOOK.MONTH

1
2
3
4
5
6
7
8

01JAN2003
01APR2003
01JUL2003
01OCT2003
01JAN2004
01APR2004
01JUL2004
01OCT2004

2679.90
2778.30
2999.00
2993.28
3132.90
2928.80
3000.80
2992.80

2679.9
2778.3
2999.0
.
3132.9
2928.8
3000.8
2992.8

Chapter 5: Deeper into Dates and Times with SAS

131

The resulting dataset QUARTERLY (above) has eight observations, four for each year,
synchronized on the QTR interval boundaries. As you can see, the data that were missing from
our original dataset (for October of 2003) are interpolated.
The second method allows you to perform simple aggregation (addition) without interpolation
of missing values. The AGGREGATE method always produces an exact result without
interpolation, and it requires that the intervals be nested. This program shows the result of a
simple aggregation on our sample data:
PROC EXPAND DATA=book.month OUT=annual FROM=MONTH TO=YEAR;
ID date;
CONVERT riders / METHOD=AGGREGATE;
RUN;

date

Riders
(thousands)

2003

.

There are 2 missing observations for this year, which
yields a missing result.

2004

35947.5

Total across all 12 months.

Example 5.4.1 The Importance of the ID Statement in PROC EXPAND
The following PROC EXPAND step has no ID statement. Let’s run it so that we can see the
assumptions that SAS makes in its absence. This illustrates why the ID statement is almost
always used with this procedure:
PROC EXPAND DATA=book.month OUT=ANNUAL FROM=MONTH TO=YEAR;
CONVERT riders;
RUN;

date

Riders
(thousands)

01JAN1960

2679.9

01JAN1961

3132.9

132

The Essential Guide to SAS Dates and Times

How did we wind up with data for 1960 and 1961 when we used data from 2003 and
2004? In the absence of an ID variable to indicate the dates, SAS will create ID values to
label the input records, and it will start from its zero point, January 1, 1960. This is why you
usually use an ID statement with PROC EXPAND.

5.4.4

Using PROC EXPAND to Interpolate Missing Values

PROC EXPAND can also be used to interpolate missing values without converting frequencies.
There are two ways to do this; use the one that fits your situation. If you are interpolating
missing values at specific points in time, leave off the FROM= and TO= options, but make sure
that you use an ID statement to indicate the variable that contains the time points of the
observed values. The time points do not have to be evenly spaced, nor do you need a record
for each time point within the interval. PROC EXPAND will read the values supplied in the ID
variable and figure out the interval to use. Remember that the data for the months of October
and November are missing in our sample table. The following program demonstrates:
PROC EXPAND DATA=book.month OUT=nomiss;
ID date;
CONVERT riders;
RUN;

date

Riders
(thousands)

01JAN2003

2679.90

01FEB2003

2421.90

01MAR2003

2704.60

01APR2003

2778.30

01MAY2003

2718.60

01JUN2003

2618.20

01JUL2003

2999.00

01AUG2003

3504.70

01SEP2003

3329.40

01OCT2003

2993.28

01NOV2003

2788.68

01DEC2003

2888.60

Chapter 5: Deeper into Dates and Times with SAS

133

The second method interpolates missing values in a time series to a specific interval. Use this
when you are interpolating to a different interval than the one given in the ID variable. It
requires the FROM= option, but leave off the TO= option, as shown here:
PROC EXPAND DATA=book.month OUT=nomiss2 FROM=MONTH;
ID date;
CONVERT riders;
RUN;

By default, the interpolation is performed by fitting the points to a cubic spline curve. You can
request other methods of interpolation with the METHOD= option on the CONVERT statement,
and these are detailed in the SAS/ETS documentation. PROC EXPAND will ignore
observations that have missing values for the ID variable, even if there are data points for the
CONVERT variable(s). Table 5.4.2 is a summary of what PROC EXPAND does when there are
missing values for the ID variable and/or CONVERT data points.
Table 5.4.2 How PROC EXPAND Handles Interpolation of Missing Values in Input Data
ID variable

Data

PROC EXPAND Will

Missing

Missing

Interpolate

Not Missing

Missing

Interpolate

Missing

Not Missing

Ignore

5.4.5 The OBSERVED= Option for the CONVERT Statement in PROC EXPAND
As with the other uses of SAS date, time, and datetime intervals, the default for PROC
EXPAND is to consider the values as being from the beginning of the intervals provided in the
FROM= and TO= options. This is not always the case with real-world data, and it can cause
very different results, especially if the values are not measured at the beginning of the given
interval(s), or they do not represent a single observed value for a specific point in time. You
can control how the SAS intervals are used through with the OBSERVED option on the
CONVERT statement. There are five different values for the OBSERVED= option, as shown in
Table 5.4.3:

134

The Essential Guide to SAS Dates and Times

Table 5.4.3 Values for the OBSERVED= option
BEGINNING

Beginning of the period

MIDDLE

Middle of the period

END

End of the period

TOTAL

Totals for the period

AVERAGE

Averages across the period

Example 5.4.2 shows how the different values of the OBSERVED= option affect our sample
data when we increase and decrease the sampling frequency. The program below shows the
code to increase the sampling frequency. It also shows how to rename your output variables in
the CONVERT statement by placing an equals sign (=) after the dataset variable and
providing the new variable name afterwards.
Example 5.4.2 Effect of Different Values for OBSERVED= Option on Increased
Frequency
/* Create weekly datasets from monthly data using different OBSERVED=
options */
PROC EXPAND DATA=book.month OUT=seven1 FROM=MONTH TO=WEEK;
ID date;
CONVERT riders=beginning / OBSERVED=BEGINNING /* Stores result in
variable named ‘beginning’ */;
RUN;
PROC EXPAND DATA=book.month OUT=seven2 FROM=MONTH TO=WEEK;
ID date;
CONVERT riders=middle / OBSERVED=MIDDLE;
RUN;
PROC EXPAND DATA=book.month OUT=seven3 FROM=MONTH TO=WEEK;
ID date;
CONVERT riders=end / OBSERVED=END;
RUN;
PROC EXPAND DATA=book.month OUT=seven4 FROM=MONTH TO=WEEK;
ID date;
CONVERT riders=total / OBSERVED=TOTAL;
RUN;

Chapter 5: Deeper into Dates and Times with SAS

135

PROC EXPAND DATA=book.month OUT=seven5 FROM=MONTH TO=WEEK;
ID date;
CONVERT riders=average / OBSERVED=AVERAGE;
RUN;
/* Put all EXPAND datasets together for side-by-side display */
DATA compare_lo;
MERGE seven1 seven2 seven3 seven4 seven5;
BY date;
RUN;

The data set COMPARE_LO is shown here:
DATE

BEGINNING MIDDLE

END

TOTAL

AVERAGE

29DEC2002

2770.19

.

.

580.484

3260.80

05JAN2003

2573.61

.

.

597.974

2897.25

12JAN2003

2449.83

2708.88

.

608.442

2638.87

19JAN2003

2393.59

2536.09

.

613.169

2472.89

26JAN2003

2391.28

2436.82

2652.65

613.550

2384.91

02FEB2003

2429.28

2398.83

2506.22

610.979

2360.52

09FEB2003

2493.99

2409.06

2428.26

606.851

2385.33

16FEB2003

2571.80

2454.40

2406.10

602.561

2444.93

23FEB2003

2649.08

2521.78

2427.05

599.504

2524.93

As you can see, the OBSERVED= option has a very large effect on the results that PROC
EXPAND yields. The BEGINNING column is the default, and that is the interpolation
calculated if the numbers are measured at the beginning of the month. MIDDLE and END do
the calculation as if the numbers were measured at the middle and the end of the month,
respectively. That is why the interpolated values are missing in those columns in the above
chart. The numbers are not available until the beginning of the interval (the beginning of the
week containing the middle and end, respectively, of the month).
If you’re measuring totals (which we are, since this is mass transit ridership data), the values
are radically different. TOTAL means that the number being interpolated is not representative
of a single point in the TO= interval, but that it is obtained across the duration of the TO=
interval. Therefore, the numbers in that column of the above table represent the number of
riders per week. AVERAGE considers the numbers to be the TO= interval average.

136

The Essential Guide to SAS Dates and Times

In contrast to Example 5.4.2, Example 5.4.3 shows the effect of the OBSERVED= option on a
lower sampling frequency. Remember, since our original data had missing values, some
interpolation will take place.
Example 5.4.3 Effect of Different Values for OBSERVED= Option on Lowered
Frequency

DATE BEGINNING

MIDDLE

END

TOTAL

AVERAGE

2003

2679.9

2764.22

2888.6

34476.22

2861.76

2004

3132.9

2972.48

3038.4

35947.50

2996.92

BEGINNING, MIDDLE, and END don’t give us a very good idea of yearly ridership, because
they are considering the entire ridership as occurring on the beginning, middle, or end of the
FROM= interval. TOTAL is the value for the entire year, and AVERAGE is calculated on the
monthly values. However, all of these values are calculated with interpolation of the missing
values in October and November of 2003.
PROC EXPAND has many more capabilities, and the preceding examples give only the most
basic information on how to use this powerful procedure with time series data. You can refer
to the documentation for SAS/ETS to get a much more complete explanation of PROC
EXPAND and its options.

5.5 International Date, Time, and Datetime Formats and
Informats
Version 9 of SAS has formats for dates and times in languages other than United States
English. It is included in Base SAS as a part of National Language Support (NLS). The key to
NLS is in the LOCALE= or DFLANG= system options. The LOCALE= option is defined in the
SAS configuration file when it is installed by your SAS administrator, but it may be changed
with an OPTIONS statement, or inside the OPTIONS window. The LOCALE= option implicitly
sets two other options which can affect dates, times, and datetime values in SAS. The
DATESTYLE= option determines how the ANYDT informats will interpret character strings
where month, day, and year are ambiguous. The DFLANG= option defines the default
language that the SAS System will use.

Chapter 5: Deeper into Dates and Times with SAS

137

There are a few specific date formats for Taiwanese, Japanese, and Hebrew, but you can
consider the majority of international formats and informats as falling into one of two informal
categories: the “EUR” category, or the “NL” category. These categories are based on the first
two or three letters of the format or informat name. The “EUR” category will select the
language based on either the DFLANG= system option or by allowing you to replace the
“EUR” in the format name with a specific language abbreviation. Using the language
abbreviations is handy if you are working with many languages on the same output, because
they allow you to specify the language without regard to the DFLANG= option. The “NL”
category is controlled by the LOCALE= system option.

5.5.1 “EUR” Formats and Informats
Each of these formats and informats correspond to an English language format or informat.
However, the minimum, maximum, and default widths for the format or informat are
dependent upon the language being used at the time. Tables 5.5.1 and 5.5.2 list the English
language formats and their EUR format names, and the EUR informats.
Table 5.5.1 International Format Names and Their English Language Equivalents
English language format name

International format name

DATE.

EURDFDE.

DATETIME.

EURDFDT.

DDMMYY.

EURDFDD.

DOWNAME.

EURDFDWN.

MONNAME.

EURDFMN.

MONYY.

EURDFMY.

WEEKDATX.

EURDFWKX.

WEEKDAY.

EURDFDN.

WORDDATX.

EURDFWDX.

138

The Essential Guide to SAS Dates and Times

Table 5.5.2 International Informat Names and Their English Language Equivalents
EURDFDEw.

Reads international date values in the form ddmonyy(yy), where dd represents the
day of the month, mon is the three-letter month abbreviation in the language specified
by the DFLANG= system option, or by the appropriate three-letter prefix, and yy(yy) is
the two- or four-digit year.

EURDFDTw.

Reads international datetime values in the form ddmonyy hh:mm:ss.ss or ddmonyyyy
hh:mm:ss.ss

EURDFMYw.

Reads month and year date values in the form monyy or monyyyy

You may replace the “EUR” with a specific three-letter language prefix in any of the above
formats or informats to define the language that you wish to use. This overrides the DFLANG=
system option, and is a good way to display dates in multiple languages simultaneously. Table
5.5.3 is a list of all the valid languages with their three-letter prefix. In addition, we’ll show the
effect of using each three-letter prefix on the EURDFWKX. format by using the reference date
of Monday, August 18, 1997. As a comparison, Table 5.5.3 also includes the reference date
formatted as the English equivalent WEEKDATX.
Table 5.5.3 International Date Formats with Language Abbreviations
LANGUAGE
PREFIX

LANGUAGE

FORMAT
NAME

FORMATTED DATE

WEEKDATX.

Monday, 18 August 1997

AFR

Afrikaans

AFRDFWKX.

Maandag, 18 Augustus 1997

CAT

Catalan

CATDFWKX.

Dilluns, 18 Agost 1997

CRO

Croatian

CRODFWKX.

ponedjeljak, 18 kol 1997

CSY

Czech

CSYDFWKX.

pondělí, 18 srpen 1997

(continued on next page)

Chapter 5: Deeper into Dates and Times with SAS

Table 5.5.3 (continued)
LANGUAGE
PREFIX

LANGUAGE

FORMAT
NAME

FORMATTED DATE

DAN

Danish

DANDFWKX.

mandag, den 18. august 1997

NLD

Dutch

NLDDFWKX.

maandag, 18 augustus 1997

FIN

Finnish

FINDFWKX.

Maanantaina, 18. elokuuta 1997

FRA

French

FRADFWKX.

Lundi 18 août 1997

DEU

German

DEUDFWKX.

Montag, 18. August 1997

HUN

Hungarian

HUNDFWKX.

1997.augusztus 18., hétfő

ITA

Italian

ITADFWKX.

Lunedì, 18 Agosto 1997

MAC

Macedonian

MACDFWKX.

ponedelnik, 18 avgust 1997

NOR

Norwegian

NORDFWKX.

mandag, 18 august 1997

POL

Polish

POLDFWKX.

poniedziałek, 18 sierpień 1997

PTG

Portuguese

PTGDFWKX.

Segunda-feira, 18 de agosto de 199

RUS

Russian

RUSDFWKX.

Понедельник, 18 Август 1997

ESP

Spanish

ESPDFWKX.

lunes, 18 de agosto de 1997

(continued on next page)

139

140

The Essential Guide to SAS Dates and Times

Table 5.5.3 (continued)
LANGUAGE
PREFIX

LANGUAGE

FORMAT
NAME

FORMATTED DATE

SLO

Slovenian

SLODFWKX.

ponedeljek, 18 avgust 1997

SVE

Swedish

SVEDFWKX.

Måndag, 18 augusti 1997

FRS

Swiss_French

FRSDFWKX.

Lundi 18 août 1997

DES

Swiss_German

DESDFWKX.

Montag, 18. August 1997

5.5.2 “NL” Formats
The output from the “NL” series of formats is defined by the LOCALE= system option. Unlike
the “EUR” series, you cannot specify a language other than the one defined by the current
value of the LOCALE= option. Use these formats when your output may be generated in
several different locations around the world, but you don’t have to display multiple languages
within the same output.
These formats work by converting the SAS date, time, or datetime value to that of the specified
locale, and then formatting the result. These formats are also noteworthy in that the result is
left-justified, as opposed to the right-justification of most of the other date, time, and datetime
formats. This is true for all ODS destinations as well as for traditional column-based output. Of
course, with ODS destinations, the justification of the column will be performed according to
any STYLE in effect. Table 5.5.4 lists the “NL” series formats available and the default width,
width range, and English language equivalent for each format.

Chapter 5: Deeper into Dates and Times with SAS

141

Table 5.5.4 “NL” Series Formats

CATEGORY
Date

Datetime

Time

FORMAT
NAME

ENGLISH
LANGUAGE
FORMAT
NAME

DEFAULT
WIDTH

WIDTH
RANGE

NLDATEw.

DATE.

20

20–100

NLDATEMNw.

MONNAME.

4

4–200

NLDATEWw.

WORDDATE. or
WORDDATX.

20

20–200

NLDATEWNw.

DOWNAME.

10

4–200

NLDATMw.

DATETIME.

30

10–200

NLDATMAPw.

DATEAMPM.

32

16–200

NLDATMTMw.

None. Displays
time-of-day from
datetime value in
local time format.

16

16–200

NLDATMWw.

DTWKDATX.

30

16-–200

NLTIMAPw.

TIMEAMPM.

10

4–200

NLTIMEw.

TIME.

20

10–200

Unlike the
Englishlanguage
formats,
fractional
seconds
may not
be used.

Table 5.5.5 shows the difference between two different LOCALE settings when each of the
following formats are used.

142

The Essential Guide to SAS Dates and Times

Table 5.5.5 Differences in the “NL” Formats Based on LOCALE= Option Setting
FORMAT NAME

OPTIONS LOCALE=
ENGLISH_US

OPTIONS LOCALE=
SPANISH_SPAIN

NLDATE32.

April 16, 2006

16 de abril de 2006

NLDATEMN32.

April

abril

NLDATEW32.

Sunday, April 16, 2006

domingo 16 de abril de 2006

NLDATEWN32.

Sunday

domingo

NLDATM32.

16Apr04:18:25:45

16 de abril de 2004 18H25

NLDATMAP32.

April 16, 2004 06:25:45 PM

16 de abril de 2004 18H25

NLDATMTM32.

18:25:45

18H25

NLDATMW32.

Fri, Apr 16, 2004 06:25:45 PM

vie 16 de abr de 2004 18H25

NLTIMAP32.

06:25:45 PM

18H25

NLTIME32.

18:25:45

18H25

Table 5.5.6 shows the available “NL” series informats, their default width specification, the
width range, and the English language informat to which it is similar.
Table 5.5.6 “NL” Series Informats
FORMAT
NAME

DEFAULT
WIDTH

WIDTH
RANGE

ENGLISH LANGUAGE
EQUIVALENT INFORMATS

Date

NLDATEw.

20

20–100

DATE. and WORDDATX.

Datetime

NLDATMw.

30

10-–200

DATETIME.

Time

NLTIMAPw.

10

4–200

TIME., with AM/PM

NLTIMEw.

20

10–200

TIME.

CATETORY

Chapter 5: Deeper into Dates and Times with SAS

143

The whole point of the “NL” series of formats and informats is that you do not have to worry
about the specific language that will be using the format or informat. The LOCALE= option will
take care of it. In this way, the same SAS program can be used anywhere, and the output will
be appropriate to the local language. It is important to understand that the “NL” series of
formats and informats works just as well with the English language, so there’s no need to use
SAS program code beyond the LOCALE= option to switch between English language
formats/informats and other languages, unless you need a specific English language format
that does not have an “NL” equivalent.

5.5.3 Specific Language Date Formats and Informats
In addition to the “NL” and “EUR” series of formats and informats, SAS has a few other date
formats and informats for specific languages. Some of these are available in Version 8, and
are noted as such.

5.5.3.1 Hebrew Date Formats (Version 9)
HDATEw. displays a SAS date value in Hebrew. You will need the correct character
encoding installed on your system to display this correctly. The SAS date will be displayed as
yyyy mmmmm dd, where dd is the day-of-the-month, mmmmm represents the month’s
name in Hebrew, and yyyy is the year. w can be from 9–17, with a default width of 17,
and it is right-justified. Use odd numbers for w to get the best display.
HEBDATEw. displays a SAS date value according to the Jewish calendar. w can be from 7–
24, with a default width of 16, and it is right-justified. There are three forms of the display,
long, default, and short, dependent upon the width specified. Again, you will need the correct
character encoding installed on your system, or you will get substitutions for non-printing
characters.

5.5.3.2 Japanese and Taiwanese Date Formats (Versions 8 and above)
MINGUOw. displays a SAS date value as a Taiwanese date value in the form
yy(yy)mmdd, where yy(yy) is the year, mm is the number of the month, and dd is the
day of the month. w can range from 1–10, with a default width of 8, and it is left-justified,
and zero-filled. The Taiwanese calendar uses 1912 as the base year (i.e., 01/01/01 is
January 1, 1912). Also, the year values continue to increase past 100; they do not cycle.
January 1, 2012 is “100/01/01”, not “00/01/01”.

144

The Essential Guide to SAS Dates and Times

NENGOw. writes a SAS date value in the form e.yymmdd, where e is the first letter of the
name of the emperor (Meiji, Taisho, Showa, or Heisei), yy is the year, mm is the month, and
dd is the day of the month. w can be from 2–10, with a default width of 10, and it is leftjustified. SAS will omit the period if w isn’t big enough.

5.5.3.3 Japanese and Taiwanese Date Informats (Versions 8 and above)
JDATEMYDw. allows you to convert Japanese Kanji in the form yy(yy)mondd to SAS date
values, where yy(yy) is the year, mon is the Kanji representation of the name of the month,
and dd represents the day of the month. w can be from 12–32, with a default width of 12.
You can separate (yy)yy, mon, and dd with special characters or blanks, but you must make
sure that the width specification allows for any blanks and/or special characters in the input
field. Two-digit years will be translated according to the YEARCUTOFF= option.
JNENGOw. reads Japanese Kanji date values in the form yymmdd, where yy is the year,
mm is the Kanji representation of the name of the month, and dd represents the day of the
month. Since yy is two digits long, this informat is always affected by the YEARCUTOFF=
option. w can be from 16–32, with a default width of 16. You can separate yy, mon, and
dd with special characters or blanks, but you must make sure that the width specification
allows for any blanks and/or special characters in the input field.
MINGUOw. converts a Taiwanese date value into a SAS date value in the form
yy(yy)mmdd, where yy(yy) is the year, mm is the number of the month, and dd is the
day of the month. w can be from 6–10, with a default width of 6. You may use separators
such as blanks, dashes, or slashes between the year, month, and day values, but they must be
present between all of the values. The Taiwanese calendar uses 1912 as the base year (i.e.,
01/01/01 is January 1, 1912). In addition, the year values continue to increase past 100;
they do not cycle. January 1, 2012 is “100/01/01”, not “00/01/01”.

5.6 Other Software and Their Dates (Excel, Oracle, DB2)
Most other software packages keep their dates in some sort of numerical form in much the
same way that SAS does, while some software packages have a special variable type for
dates. Microsoft Excel stores dates as integers, but it uses January 1, 1900 instead of January
1, 1960 as day zero. Times are stored in Excel as fractions of days, so noon of a given day is
.5 (exactly one half of a day.) Datetime values are stored in Excel as the day relative to
01/01/1900 plus the fraction of the day. In Excel, 6 p.m., on January 1, 1900 is
represented as .75. Excel also has a major limitation on its dates: it cannot store dates as

Chapter 5: Deeper into Dates and Times with SAS

145

negative numbers, so any date prior to January 1, 1900 is going to be represented by a
character string, not an Excel date value. This may cause problems if you are importing data
from Excel. If you want to do the conversion from/to SAS date, time, and datetime values
to/from Excel date and time values, you can use the following conversion table:
Table 5.6.1 Mathematical Conversions between SAS and Excel
To convert Excel values into SAS values
Creating a SAS date: Subtract 21916 from the Excel date value.
Creating a SAS time: Multiply the Excel time value (fraction of a day) by 86400 (# of seconds in a day).
Creating a SAS datetime: Subtract 21916 from the Excel date and time value, then multiply by 86400;

To convert SAS values into Excel values
Creating an Excel date value: Add 21916 to the SAS date value. This works only for dates after
December 31, 1899.
Creating an Excel time value: Divide the SAS time value by 86400.
Creating an Excel date and time value: Divide the SAS datetime value by 86400 (seconds in a day), then add
21916 to that. Again, this works only for dates after December 31, 1899.

What do you do if you have dates before January 1, 1900 to convert? Going to Excel, you
will have to store them as character strings, and you won’t be able to use any of the Excel
math functions on them. On the other hand, if you are going from Excel to SAS, then you can
take the character string from the imported data set and use the INPUT( ) function (Section
3.3.2) to get a valid SAS date or datetime value. The ANYDT informats may also prove useful
in situations like this. Example 5.6.1 shows how to use an INPUT statement and a DATA step
to process a CSV file when you have mixed character and date values from Excel. Note that
we have to use the OPTIONS YEARCUTOFF= statement to process the two-digit year values in
the sample file correctly.

146

The Essential Guide to SAS Dates and Times

Example 5.6.1 Reading an Excel CSV File with Dates Prior to January 1, 1900

THE CSV FILE
“EXCEL_TEST.CSV”
01/01/00
01JAN1899

Not an Excel date value, so it is not in the Excel date format for the column.

01/01/01

The Log
117 OPTIONS YEARCUTOFF=1895; /* If not specified, the first and last dates
in the “excel_test.csv” file will be in the 21st century! */

118
119
120
121
122
123
124

OPTIONS DATESTYLE=DMY;
DATA convert_excel;
INFILE "examples\excel_test.csv" PAD MISSOVER;
INPUT @1 date anydtdte10.;
PUT _infile_;
PUT date= +5 date= worddate.;
RUN;

NOTE: The infile "examples\excel_test.csv" is:
File Name=C:\book\examples\excel_test.csv,
RECFM=V,LRECL=256
01/01/00
date=-21914

date=January 1, 1900

01JAN1899
date=-22279

date=January 1, 1899

01/01/01
date=-21549

date=January 1, 1901

Chapter 5: Deeper into Dates and Times with SAS

147

Since the dates are in the CSV file with two different formats (DATE9. and MMDDYY.), we
can’t use either of those informats to process the input field. The ANYDTDTE. informat allows
us to process this easily.
These are conversion issues specific to Excel that may arise when you are trying to import or
export data to/from Excel. When you import data from other packages into SAS using the
IMPORT procedure, or one of the database engines, SAS should understand and convert the
dates, even though the reference date may differ. There are exceptions to this rule, one of
which is using a WHERE clause inside PROC SQL for foreign databases. You will have to
know the date, time, or datetime format for the foreign database to select records based on
dates, times, or datetimes.
However, before assuming that your dates are numeric (or of type “date”), make sure that you
are not working with character strings masquerading as dates. If you have a character string,
you will have to convert it to a SAS date, time, or datetime yourself with the INPUT( ) function
(Section 3.3.2)
Sending dates to other databases and software packages should be fine if you use the
EXPORT procedure or one of the database engines. If you are determined to send dates to
another database or software package the hard way, then you will have to produce SAS
date, time, or datetime values as character strings in the format of the other software. You can
use a picture format and the PUT statement to accomplish this, as long as you know the correct
representation of the package for which you are creating the data. For details on creating
picture formats, see Sections 2.5 and 2.6. Example 5.6.2 shows how this is done for a DB2
database.
Example 5.6.2 Writing Datetime Values for DB2 Using a Picture Format
PROC FORMAT;
PICTURE dbdate
LOW-HIGH = ‘%Y-%0m-%0d:%0H:%0M:%0S’ (DATATYPE=DATETIME)
. - .Z = ‘0000-00-00:00:00:00’;
RUN;
DATA _NULL_;
now = ‘01JUL2005:20:18:32’dt;
PUT “now displayed as datetime value: “ now;
PUT “now displayed as datetime18.: “ now DATETIME18.;
PUT “now displayed as dbdate.: “ now DBDATE.;
RUN;

148

The Essential Guide to SAS Dates and Times

The Log
now displayed as datetime value: 1435868312
now displayed as datetime18.:
01JUL05:20:18:32
now displayed as dbdate.:
2005-07-01:20:18:32

APPENDIX A A Quick Reference Guide to SAS Date, Time, and Datetime Formats
This table shows the result when the same date, time, or datetime value is displayed with the corresponding
format, using the default length for the given format.

150

Index
A
%A date directive 56
%a date directive 56
AFR (Afrikaans) language prefix 138
ampersand (&) 111
ANYDTDTEw. informat 79–80
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
CSV files and 147
DATESTYLE= system option and 8–10,
78, 80, 82, 135
Excel conversions and 145
ANYDTDTMw. informat 81
DATESTYLE= system option and 8,
10, 78, 135
Excel conversions and 145
ANYDTTMEw. informat 82
DATESTYLE= system option and 8,
10, 78, 135
Excel conversions and 145
automatic macro variables 108–109
B
%B date directive 56
%b date directive 56
C
calculations
INTCK( ) function and 98–102
INTNX( ) function and 102–106
number of days between dates 93–94
number of years between dates
94–96
CALL SYMGET( ) function 111–113
CALL SYMPUT( ) function 108, 111–113
case sensitivity 56–57

CAT (Catalan) language prefix 138
character constants 93
character strings
DATETIME. informat 70
informats and 77
PUT() function and 60–61
character variables
date, time 3
INPUTC( ) function 67–68
INPUT( ) function and 67
PUT() function and 60
PUTN( ) function and 61
constants, date and time as 3–4
conversions, between SAS and Excel
145
CONVERT statement, EXPAND procedure
converting to higher frequency 129
METHOD= option 131, 133
OBSERVED= option 133–136
CRO (Croatian) language prefix 138
CSV files 145–147
CSY (Czech) language prefix 138
custom formats 54–60
D
%d date directive 56, 59
DAN (Danish) language prefix 139
DATA step
Excel conversions 145–146
FORMAT statement 16–17
%LET statement and 111
DATALINES statement 66–67, 79
DATATYPE= option 56, 59
DATDIF( ) function 93–94
DATE7. format 108
DATE9. format 20, 108, 147
date directives, picture format 56–60

152

Index

&DATE macro variable 110–111
DATE system option 5, 11
DATEAMPMw.d format 49–50
international format for 141
quick reference 149
DATE() function 86
&DATEJ macro variable 110
DATEPART() function 87
date directives and 59, 60
datetime formats and 47
dates
as constants 3–4
automatic macro variables 108–109
CALL SYMPUT( ) function and
111–113
counters for 2
creating character strings 60–61
custom formats 54–60
datetime values and 19, 47–49
default justification 19
Excel and 144–145
external representation of 3
formats for 19–43
graphing 122–126
Hebrew formats 143
in titles 109–110, 111
incrementing values for 16
informats for 65, 67, 70–75, 78
internal representation of 2
international formats and informats
135–143
interval definitions 96–97
interval functions 98–106
Japanese formats 143–144
Japanese informats 144
quick reference 149
shifting intervals 113–122
%SYSFUNC( ) macro function and
110–111
system options and 5–11
Taiwanese formats 143–144
Taiwanese informats 144

width specification 12–13, 18, 19
YEARCUTOFF= system option and
64–65
DATESTYLE= system option 5, 8–10, 78
ANYDTDTEw. informat and 80, 82
ANYDTDTMw. informat and 81
LOCALE= system option and 135
missing values example 83
DATESTYLE=DMY system option 8, 78,
83
DATESTYLE=DYM system option 8, 78,
83
DATESTYLE=LOCALE system option 8, 78
DATESTYLE=MDY system option 8, 78,
83
DATESTYLE=MYD system option 8, 78,
83
DATESTYLE=YDM system option 8, 78,
83
DATESTYLE=YMD system option 8, 78,
83
datetime values
as constants 3–4
automatic macro variables and
109–110
CALL SYMPUT( ) function and
111–113
custom formats for 54–60
date formats and 19, 47–49
default justification 19
Excel and 144–145
external representation of 3
formats for 47–54
incrementing values for 16
informats for 67, 77, 78
internal formats and informats
135–143
internal representation of 2
interval definitions 97–98
interval functions 98–106
quick reference 149
shifting intervals 113–122

Index

%SYSFUNC( ) macro function and
110–111
width specification 12–13, 44, 47
YEARCUTOFF= system option and
64–65
DATETIME() function 86
DATETIMEw. informat 77
ANYDTDTEw. informat and 79
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
character strings and 70
international format for 142
DATETIMEw.d format 50–51
international format for 137, 141
quick reference 149
DATEw. format 20
DTDATEw. format and 51
international format for 137, 140
quick reference 149
DATEw. informat 70–71
ANYDTDTEw. informat 79
ANYDTDTMw. informat 81
ANYDTTMEw. informat 82
international format for 142
DATJUL() function 89
DAY interval 96
INTCK( ) function 100
INTNX( ) function 104
shift point 114
DAY() function 87
DAYw. format 20, 149
DB2 databases 147–148
DDMMYYB. format 22, 149
DDMMYYC. format 22, 149
DDMMYYD. format 22, 149
DDMMYYN. format 22, 149
DDMMYYP. format 22, 149
DDMMYYw. format 21, 38
DDMMYYxw. format and 22
international format for 137
MMDDYYw. format and 24

quick reference 149
YYMMDDw. format and 38
DDMMYYw. informat 71
ANYDTDTEw. informat and 79
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
DATESTYLE= system option 78
DDMMYYxw. format 21–22
MMYYxw. format and 26
YYMMxw. format and 37
YYQxw. format and 41
DES (Swiss German) language prefix
140
DEU (German) language prefix 139
DFLANG= system option 135, 138
DHMS() function 90
dollar sign ($) 67
dot (.)
See period
DOWNAMEw. format 18, 22–23
international format for 137, 140
quick reference 149
DTDATE9. format 51
DTDATEw. format 51–52
DATEw. format and 20
quick reference 149
DTDAY interval 97
INTCK( ) function 100
INTNX( ) function 104
shift point 115
DTHOUR interval 98, 115
DTMINUTE interval 98, 115
DTMONTH interval 98
INTNX( ) function 105
shift point 115
DTMONYYw. format 52
MONYYw. format and 28
quick reference 149
DTQTR interval 98
INTNX( ) function 103, 105
shift point 115
DTRESET system option 5, 11

153

154

Index

DTSECOND interval 98
shift point 115
DTSEMIMONTH interval 97
INTNX( ) function 104
shift point 115
DTSEMIYEAR interval 98
INTNX( ) function 103, 105
shift point 115
DTTENDAY interval 97
INTNX( ) function 104
shift point 115
DTWEEK interval 97
INTNX( ) function 104
shift point 115
DTWEEKDAY interval 97
INTNX( ) function 104
shift point 115
DTWKDATXw. format 52–53
international format for 141
quick reference 149
DTYEAR interval 98
INTNX( ) function 103, 105
shift point 115
DTYEARw. format 53, 149
DTYYQCw. format 53–54, 149
Dutch (NLD) language prefix 139
E
equals sign (=) 134
_ERROR_ automatic variable 68–70
ESP (Spanish) language prefix 139
"EUR" formats 137–140
"EUR" informats 137–140
EURDFDD. format 137
EURDFDEw. format 137, 138
EURDFDN. format 137
EURDFDTw. format 137, 138
EURDFDWN. format 137
EURDFMN. format 137
EURDFMYw. format 137, 138

EURDFWDX. format 137
EURDFWKX. format 137, 138
Excel (Microsoft) 144–145
EXPAND procedure
capabilities 127–128
CONVERT statement 133–136
converting to higher frequency 129
FROM= option 132–133, 136
ID statement 129, 131–133
interpolating missing values 127,
132–133
TO= option 130, 132–133, 135
EXPORT procedure 147
exporting data 147
external representation, date and time 3
F
FIN (Finnish) language prefix 139
FOOTNOTE statement 109
FORMAT procedure
date directives and 58
PICTURE statement 54, 147
VALUE statement 54–56
FORMAT statement
date directives and 58
functionality 16–18
INFORMAT statement and 66
formats 16, 17–18, 65
custom 54–60
date constants and 4
"EUR" 137–140
external representation of date, time
and 3
for date values 19–43
for datetime values 47–54
for time values 43–47
graphing dates and 122–123
Hebrew 143
Japanese 143–144
language-specific 137–140
"NL" 140–143

Index

PUT( ) function and 60–61
quick reference 149
syntax structure 18
Taiwanese 143–144
using wrong 68
FRA (French) language prefix 139
FROM= option, EXPAND statement
132–133, 136
FRS (Swiss French) language prefix 140
functions
calculating intervals 93–106
creating date, time 89–92
current date, time 86
date directives and 59
extraction 86–88
G
German (DEU) language prefix 139
graphing dates 122–126
Gregorian year
JULIANw. informat 71
PDJULG4. informat 73
PDJULGw. format 28
PDJULIw. format 29
PDJULIw. informat 73
H
%H date directive 56
HDATEw. format 143
HEBDATEw. format 143
Hebrew date formats 143
HHMMw.d format 44, 45, 149
HMS() function 91
HOUR interval 98
INTNX( ) function 105, 106
shift point 115
HOUR() function 87
HOURw.d format 44–45, 149
HUN (Hungarian) language prefix 139

155

I
%I date directive 56
IBM mainframe time values 75, 77
ID statement, EXPAND procedure 129,
131–133
IMPORT procedure 147
importing data 147
INFORMAT statement 66–68
INPUT statement and 65
informats 3, 65
ANYDT variants 77–83
"EUR" 137–140
for dates 70–75
for datetime 77
for time 75–77
Hebrew 143
INFORMAT statement 65–68
Japanese and Taiwanese 144
language-specific 137–140
"NL" 142
using wrong 68–70
INPUT statement
Excel conversions and 145
informats with 65–67
YEARCUTOFF= system option and 5
INPUTC( ) function 67
INPUT( ) function
date values and 7
Excel conversions and 145, 147
functionality 3
informats and 65, 67–68
YEARCUTOFF= system option and 5
INPUTN( ) function 67
INTCK( ) function 113, 116
calculating intervals 98–102
internal representation, date and time 2
interval multipliers
EXPAND procedure and 127
graphs and 122–126
shifting intervals and 117–122

156

Index

intervals
basics of 96–98
custom 117–119
definitions, standard 96–97
INTCK( ) function 98–102
INTNX( ) function 102–106
measuring 121
number of days between dates
93–94
number of years between dates
94–96
shifting 113–122
INTNX() function 98, 102–106
shifting intervals 113, 121
YRDIF( ) function and 96
ITA (Italian) language prefix 139
J
%j date directive 57
Japanese date formats 143–144
Japanese date informats 144
JDATEMYDw. informat 144
Jewish calendar 143
JNENGOw. informat 144
Joshi, Bhairav 2
JULDATE( ) function 87
JULDATE7( ) function 87
JULDAYw. format 23, 149
Julian date
JULDATE( ) function 87
JULDATE7( ) function 87
JULDAYw. format 23
JULIANw. format 24
JULIANw. informat 71
PDJULG. informat 73
PDJULG4. informat 73
PDJULGw. format 28, 29
PDJULI1. format 30
PDJULIw. format 29–30
PDJULIw. informat 39, 73
JULIANw. format 24, 149

JULIANw. informat 71–72
ANYDTDTEw. informat and 79
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
justification
date formats 19
PDJULIw. format and 29
K
Kanji representation 144
L
language-specific formats 137–140
language-specific informats 137–140
%LEFT( ) macro function 110
LENGTH statement 12–13
%LET statement 108, 111
LISTING destination 19
literal values
quotation marks and 3
YEARCUTOFF= system option and
64–65
LOCALE= system option 135, 140,
142–143
M
%M date directive 57
%m date directive 57, 59
MAC (Macedonian) language prefix 139
macro calls 57
macro functions, date and time in
110–111
macro variables
CALL SYMPUT() function and
111–113
dates and 108–109
quotation marks and 109
MDY() function 91–92
METHOD= option, CONVERT statement
(EXPAND) 131, 133
Microsoft Excel 144–145

Index

MINGUOw. format 143
MINGUOw. informat 144
MINUTE interval 98
INTNX( ) function 105
shift point 115
MINUTE( ) function 87
missing values
DATESTYLE= system option 83
EXPAND procedure and 127,
132–133
symbol for 58
wrong informats and 68–70
MMDDYY10. format 17, 24
MMDDYYB. format 25, 149
MMDDYYC. format 25, 149
MMDDYYD. format 25, 149
MMDDYYN. format 25, 149
MMDDYYP. format 25, 149
MMDDYYw. format 24
CSV files and 147
MMDDYYxw. format and 25
quick reference 149
YYMMDDw. format and 38
MMDDYYw. informat 72
ANYDTDTEw. informat and 79, 80
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
DATESTYLE= system option and 78
MMDDYYxw. format 25
MMYYxw. format and 26
YYMMxw. format and 37
YYQxw. format and 41
MMSSw.d format 43, 45, 149
MMYYC. format 27, 149
MMYYD. format 27, 149
MMYYN. format 27, 149
MMYYP. format 27, 149
MMYYw. format 26, 149
MMYYxw. format 26–27
MONNAMEw. format 27
international format for 137, 140
quick reference 149

157

MONTH interval 97
example 129
INTCK( ) function 99–100
INTNX( ) function 105, 106
shift point 114, 120
MONTH( ) function 87
MONTHw. format 28, 149
MONYYw. format 28
DTMONYYw. format and 52
international format for 137
quick reference 149
MONYYw. informat 72–73
ANYDTDTEw. informat and 79
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
MSEC8. informat 75
N
National Language Support (NLS) 135
NENGOw. format 144
"NL" formats 140–143
"NL" informats 142
NLD (Dutch) language prefix 139
NLDATEMNw. format 141
NLDATEw. format 141, 142
NLDATEw. informat 142
NLDATEWNw. format 141
NLDATEWw. format 141
NLDATMAPw. format 141
NLDATMTMw. format 141
NLDATMw. format 141
NLDATMw. informat 142
NLDATMWw. format 141
NLS (National Language Support) 135
NLTIMAPw. format 141
NLTIMAPw. informat 142
NLTIMEw. format 141
NLTIMEw. informat 142
NODATE system option 5, 11
NOR (Norwegian) language prefix 139

158

Index

numeric variables
date, time as 3–4
functions from 89–92
INPUT( ) function and 67
LENGTH statement and 12–13
O
OBSERVED= option, CONVERT statement
(EXPAND) 133–136
OBSERVED=AVERAGE option, CONVERT
statement (EXPAND) 134–136
OBSERVED=BEGINNING option,
CONVERT statement (EXPAND)
134–136
OBSERVED=END option, CONVERT
statement (EXPAND) 134–136
OBSERVED=MIDDLE option, CONVERT
statement (EXPAND) 134–136
OBSERVED=TOTAL option, CONVERT
statement (EXPAND) 134–136
ODS destinations 19, 140
OPTIONS statement
DATE/NODATE system option 5, 11
DATESTYLE= system option 8–10
LOCALE= system option 135
YEARCUTOFF= system option 6–7,
28–29, 145
OS TIME macro 75, 77
P
%p date directive 57
PDF destination 19
PDJULG. informat 73
PDJULG4. informat 73
PDJULGw. format 28–29
PDJULI1. format 30
PDJULIw. format 29–30
PDJULIw. informat 30, 73
PDTIME4. informat 75
period (.)
format syntax and 18

in informats 65
missing values and 58
PICTURE statement, FORMAT procedure
54, 147
POL (Polish) language prefix 139
PRINT procedure 17–18
PROC step 17
PTG (Portuguese) language prefix 139
PUT _INFILE_ statement 77
PUT( ) function 60–61, 67, 111
PUTN( ) function 61, 111
Q
%QSYSFUNC( ) macro function
110–111
QTR interval 97
INTNX( ) function 105, 106
shift point 114
QTR() function 87
QTRRw. format 31, 149
QTRw. format 30, 149
quotation marks
character constants and 93
literal values and 3
macro variables and 109
R
&RAWDATE macro variable 110–111
RMFDUR4. informat 75
RTF destination 19
RUS (Russian) language prefix 139
S
%S date directive 57
sampling frequency
converting to higher 129
converting to lower 130–132
OBSERVED= option and 134–136
SAS/AF objects 65
SAS/ETS 127, 133
SAS/GRAPH 122–126

Index

SECOND interval 98
INTNX( ) function 105
shift point 115
SECOND() function 87
SEMIMONTH interval 97
INTNX( ) function 104, 106
shift point 114
SEMIYEAR interval 97
INTNX( ) function 105
shift point 114
shift operators
EXPAND procedure and 127
intervals and 113–115
slash (/) 59
SLO (Slovenian) language prefix 140
Spanish (ESP) language prefix 139
SQL procedure 147
STIMER system option 75
STIMERw. informat 75–76
SVE (Swedish) language prefix 140
Swiss French (FRS) language prefix 140
Swiss German (DES) language prefix
140
&SYSDATE automatic macro variable
108, 110
&SYSDATE9 automatic macro variable
108, 110, 111
&SYSDAY automatic macro variable
108–109, 110
%SYSFUNC( ) macro function 110–111
&SYSTIME automatic macro variable
109, 110
T
Taiwanese date formats 143–144
Taiwanese date informats 144
TENDAY interval 97
INTNX( ) function 104
shift point 114
time values
as constants 3–4

automatic macro variables and
109–110
CALL SYMPUT( ) function and
111–113
counters for 2
custom formats 54–60
default justification 19
Excel and 144–145
external representation of 3
formats for 43–47
incrementing values for 16
informats for 67, 75–77, 78
internal formats and informats
135–143
internal representation of 2
interval definitions 98
interval functions 98–106
quick reference 149
shifting intervals 113–122
%SYSFUNC( ) macro function and
110–111
width specification 12–13, 44
TIME5. format 109
TIMEAMPM11. format 17
TIMEAMPMw.d format 46
clock values and 43
international format for 141
quick reference 149
TIME() function 86
TIMEPART() function 47, 88
TIMEw. informat 76
ANDTDTEw. informat and 79
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
international format for 142
TIMEw.d format 45–46
HHMMw.d format and 44
international format for 141
quick reference 149
TITLE statement 109
titles, dates in 109–111

159

160

Index

TO= option, EXPAND procedure 130,
132–133, 135
TODAY( ) function 86
TODw.d format 47
clock values in 43
quick reference 149
TU4. informat 77
two-digit year
DATESTYLE= system option and 8
extraction functions and 86
YEARCUTOFF= system option and 5,
64–65, 77–78, 145
U
U algorithm 33, 88
%U date directive 57
V
V algorithm 34, 88
VALUE statement, FORMAT procedure
54–56
variables
See character variables
See macro variables
See numeric variables
W
W algorithm 35, 88
%w date directive 57
WEEK interval 96
example 129
INTCK( ) function 100
INTNX( ) function 104, 106
shift point 114, 116, 118
week number calculation
U algorithm 33, 38
V algorithm 34, 85
W algorithm 35, 88
WEEKDATE.37 format 18
WEEKDATEw. format 31
example 18

quick reference 149
WEEKDATXw. format and 32
WEEKDATXw. format 32
DTWKDATXw. format and 52
international format for 137–140
quick reference 149
WEEKDAY interval 96
INTCK( ) function 101
INTNX( ) function 104
shift point 114
WEEKDAY( ) function 88
WEEKDAYw. format 32–33
international format for 137
quick reference 149
WEEK() function 88
WEEKUw. format 33
quick reference 149
WEEKVw. format and 34
WEEKWw. format and 35
WEEKVx. format 34
quick reference 149
WEEKWw. format and 35
WEEKWw. format 35, 149
WHERE clause, SQL procedure 147
width specification
for date formats 12–13, 18, 19
for datetime formats 12–13, 44, 47
for time formats 12–13, 44
formats and 18, 19
informats and 65
WORDDATEw. format 35–36
&DATE macro variable and 110
FORMAT statement and 57–58
international format for 140
quick reference 149
WORDDATXw. format 36
international format for 137, 140
quick reference 149
WORDDATXw. informat 142

Index

Y
%Y date directive 57, 59
%y date directive 57
YEAR10. interval 121
YEAR interval 97
INTCK( ) function 100, 101
INTNX( ) function 105
shift point 114, 116, 120
YEARCUTOFF= system option 5–7
DATJUL( ) function and 89
Excel conversions and 145
extraction functions and 86
Japanese/Taiwanese date informats
144
MDY( ) function 91
PDJULGw. format and 28–29
PDJULI. format 30
two-digit year and 64–65, 77
YYQ( ) function 92
YEAR() function 88
YEARw. format 37
DTYEARw. format and 53
quick reference 149
Y2K problem 5, 108
YRDIF( ) function 94–96
INTCK( ) function 101, 102
YYMMC. format 38, 149
YYMMD. format 38, 149
YYMMDDB. format 40, 149
YYMMDDC. format 40, 149
YYMMDDD. format 40, 149
YYMMDDN. format 40, 149
YYMMDDP. format 40, 149
YYMMDDw. format 38–39
DATESTYLE= system option 78
quick reference 149
YYMMDDw. informat 73–74
ANYDTDTEw. informat and 79
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
DATESTYLE= system option and 78

YYMMDDxw. format 39–40
YYMMxw. format and 37
YYQxw. format and 41
YYMMN. format 38, 149
YYMMNw. informat 74
YYMMP. format 38, 149
YYMMw. format 37
YYMMxw. format 37–38
YYMONw. format 40, 149
YYQC. format 42
DDTYQCw. format and 53
quick reference 149
YYQD. format 42, 149
YYQ() function 92
YYQN. format 42, 149
YYQP. format 42, 149
YYQRC. format 43, 149
YYQRD. format 43, 149
YYQRN. format 43, 149
YYQRP. format 43, 149
YYQRw. format 42, 149
YYQRxw. format 42–43
YYQw. format 40–41, 149
YYQw. informat 74–75
ANYDTDTEw. informat and 79
ANYDTDTMw. informat and 81
ANYDTTMEw. informat and 82
YYQxw. format 41, 53
Special Characters
. (period)
format syntax and 18
in informats 65
missing values and 58
& (ampersand) 111
$ (dollar sign) 67
= (equals sign) 134
/ (slash) 59
%% date directive 57

161

162

Index

Books Available from SAS ® Press

Advanced Log-Linear Models Using SAS®
by Daniel Zelterman

Cody’s Data Cleaning Techniques Using
SAS® Software
by Ron Cody

Analysis of Clinical Trials Using SAS®: A Practical
Guide
by Alex Dmitrienko, Geert Molenberghs, Walter Offen,
and Christy Chuang-Stein

Common Statistical Methods for Clinical Research
with SAS ® Examples, Second Edition
by Glenn A. Walker

Annotate: Simply the Basics

The Complete Guide to SAS ® Indexes

by Art Carpenter

by Michael A. Raithel

Applied Multivariate Statistics with SAS® Software,
Second Edition

Data Management and Reporting Made Easy with
SAS ® Learning Edition 2.0

by Ravindra Khattree
and Dayanand N. Naik

by Sunil K. Gupta

Applied Statistics and the SAS ® Programming
Language, Fifth Edition
by Ronald P. Cody
and Jeffrey K. Smith

An Array of Challenges — Test Your SAS ® Skills

Debugging SAS ® Programs: A Handbook of Tools
and Techniques
by Michele M. Burlew

Efficiency: Improving the Performance of Your
SAS ® Applications
by Robert Virgile

by Robert Virgile

Carpenter’s Complete Guide to the SAS® Macro
Language, Second Edition
by Art Carpenter

The Cartoon Guide to Statistics
by Larry Gonick
and Woollcott Smith

Categorical Data Analysis Using the SAS ® System,
Second Edition

The Essential Guide to SAS ® Dates and Times
by Derek P. Morgan

Fixed Effects Regression Methods for Longitudinal
Data Using SAS®
by Paul D. Allison

Genetic Analysis of Complex Traits
Using SAS ®
by Arnold M. Saxton

by Maura E. Stokes, Charles S. Davis,
and Gary G. Koch

support.sas.com/pubs

A Handbook of Statistical Analyses Using SAS®,
Second Edition
by B.S. Everitt
and G. Der

Health Care Data and SAS®

Longitudinal Data and SAS®: A Programmer’s Guide
by Ron Cody
Maps Made Easy Using SAS®
by Mike Zdeb

by Marge Scerbo, Craig Dickstein,
and Alan Wilson

Models for Discrete Date
by Daniel Zelterman

The How-To Book for SAS/GRAPH ® Software

Multiple Comparisons and Multiple Tests Using
SAS® Text and Workbook Set

by Thomas Miron

In the Know... SAS® Tips and Techniques From Around
the Globe
by Phil Mason

Instant ODS: Style Templates for the Output
Delivery System

(books in this set also sold separately)
by Peter H. Westfall, Randall D. Tobias,
Dror Rom, Russell D. Wolfinger,
and Yosef Hochberg

Multiple-Plot Displays: Simplified with Macros
by Perry Watts

by Bernadette Johnson
Integrating Results through Meta-Analytic Review Using
SAS® Software
by Morgan C. Wang
and Brad J. Bushman

Learning SAS ® in the Computer Lab, Second Edition
by Rebecca J. Elliott
The Little SAS ® Book: A Primer
by Lora D. Delwiche
and Susan J. Slaughter
The Little SAS ® Book: A Primer, Second Edition
by Lora D. Delwiche
and Susan J. Slaughter
(updated to include Version 7 features)
SAS ®

The Little
Book: A Primer, Third Edition
by Lora D. Delwiche
and Susan J. Slaughter
(updated to include SAS 9.1 features)

Multivariate Data Reduction and Discrimination with
SAS ® Software
by Ravindra Khattree
and Dayanand N. Naik

Output Delivery System: The Basics
by Lauren E. Haworth

Painless Windows: A Handbook for SAS ® Users,
Third Edition
by Jodie Gilmore
(updated to include Version 8 and SAS 9.1 features)

The Power of PROC FORMAT
by Jonas V. Bilenas

PROC SQL: Beyond the Basics Using SAS®
by Kirk Paul Lafler

PROC TABULATE by Example
by Lauren E. Haworth

The Little SAS ® Book for Enterprise Guide 3.0
by Susan J. Slaughter
and Lora D. Delwiche

Professional SAS® Programmer’s Pocket Reference,
Fifth Edition

Logistic Regression Using the SAS® System:
Theory and Application
by Paul D. Allison

Professional SAS ® Programming Shortcuts,
Second Edition

support.sas.com/pubs

by Rick Aster

by Rick Aster

Quick Results with SAS/GRAPH ® Software

SAS ® Programming in the Pharmaceutical Industry

by Arthur L. Carpenter
and Charles E. Shipp

by Jack Shostak

Quick Results with the Output Delivery System

SAS® Survival Analysis Techniques for Medical
Research, Second Edition

by Sunil Gupta

by Alan B. Cantor

Reading External Data Files Using SAS®: Examples
Handbook

SAS ® System for Elementary Statistical Analysis,
Second Edition

by Michele M. Burlew

by Sandra D. Schlotzhauer
and Ramon C. Littell

Regression and ANOVA: An Integrated Approach
Using SAS ® Software

SAS ® System for Regression, Third Edition

by Keith E. Muller
and Bethel A. Fetterman

by Rudolf J. Freund
and Ramon C. Littell

SAS ® for Forecasting Time Series, Second Edition

SAS ® System for Statistical Graphics, First Edition

by John C. Brocklebank
and David A. Dickey

by Michael Friendly

The SAS ® Workbook and Solutions Set
SAS ® for Linear Models, Fourth Edition
by Ramon C. Littell, Walter W. Stroup,
and Rudolf Freund

SAS ® for Mixed Models, Second Edition
by Ramon C. Littell, George A. Milliken, Walter W.
Stroup, and Russell D. Wolfinger

SAS® for Monte Carlo Studies: A Guide for
Quantitative Researchers

(books in this set also sold separately)
by Ron Cody

Selecting Statistical Techniques for Social Science
Data: A Guide for SAS® Users
by Frank M. Andrews, Laura Klem, Patrick M. O’Malley,
Willard L. Rodgers, Kathleen B. Welch,
and Terrence N. Davidson

Statistical Quality Control Using the SAS ® System

by Xitao Fan, Ákos Felsovályi,
Stephen A. Sivo,
˝
and Sean C. Keenan

by Dennis W. King

SAS ® Functions by Example

A Step-by-Step Approach to Using the SAS ® System
for Factor Analysis and Structural Equation Modeling

by Ron Cody

by Larry Hatcher

SAS ® Guide to Report Writing, Second Edition

A Step-by-Step Approach to Using SAS ®
for Univariate and Multivariate Statistics,
Second Edition

by Michele M. Burlew

SAS ® Macro Programming Made Easy
by Michele M. Burlew

SAS ® Programming by Example
by Ron Cody
and Ray Pass

SAS ® Programming for Researchers and
Social Scientists, Second Edition

by Norm O’Rourke, Larry Hatcher,
and Edward J. Stepanski

Step-by-Step Basic Statistics Using SAS ®: Student
Guide and Exercises
(books in this set also sold separately)
by Larry Hatcher

by Paul E. Spector

support.sas.com/pubs

Survival Analysis Using SAS ®:
A Practical Guide
by Paul D. Allison

Tuning SAS ® Applications in the OS/390 and z/OS
Environments, Second Edition
by Michael A. Raithel

Univariate and Multivariate General Linear Models:
Theory and Applications Using SAS ® Software
by Neil H. Timm
and Tammy A. Mieczkowski

Using SAS ® in Financial Research
by Ekkehart Boehmer, John Paul Broussard,
and Juha-Pekka Kallunki

Using the SAS ® Windowing Environment:
A Quick Tutorial
by Larry Hatcher

Visualizing Categorical Data
by Michael Friendly

Web Development with SAS® by Example
by Frederick Pratter

Your Guide to Survey Research Using the
SAS ® System
by Archer Gravely

JMP® Books

JMP ® for Basic Univariate and Multivariate Statistics:
A Step-by-Step Guide
by Ann Lehman, Norm O’Rourke, Larry Hatcher,
and Edward J. Stepanski

JMP ® Start Statistics, Third Edition
by John Sall, Ann Lehman,
and Lee Creighton

Regression Using JMP ®
by Rudolf J. Freund, Ramon C. Littell,
and Lee Creighton

support.sas.com/pubs

Titles in Art Carpenter’s SAS Software Series
®

Quick Results with the
Output Delivery System
by Sunil K. Gupta
(Order No. A58458)

Annotate: Simply the Basics
by Art Carpenter
(Order No. A57320)

Multiple-Plot Displays:
Simplified with Macros
by Perry Wa t t s
(Order No. A58314)

Maps Made Easy
Using SAS®
by Mike Zdeb
(Order No. A57495)

The Power of
PROC FORMAT
by Jonas V. Bilenas
(Order No. A59498)

To order: support.sas.com/pubs
Or call:
(800) 727-3228



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.6
Linearized                      : Yes
XMP Toolkit                     : 3.1-701
Modify Date                     : 2006:10:11 06:26:29+04:00
Create Date                     : 2006:10:11 06:26:14+04:00
Metadata Date                   : 2006:10:11 06:26:29+04:00
Creator Tool                    : Adobe InDesign CS (3.0.1)
Format                          : application/pdf
Title                           : The Essential Guide to SAS Dates and Times
Document ID                     : uuid:19f748fc-b197-473e-b39a-bc64cac44e26
Instance ID                     : uuid:ad9490d2-c7c6-40c4-9479-ad0498d8a0e4
Producer                        : Acrobat Distiller 7.0 (Windows)
Has XFA                         : No
Page Count                      : 176
Creator                         : Adobe InDesign CS (3.0.1)
EXIF Metadata provided by EXIF.tools

Navigation menu