SAS Date & Datetime Functions

Quick reference for date and datetime handling in SAS Base. Understanding SAS's numeric date representation is essential for working with dates correctly.

How SAS Stores Dates

SAS dates are numbers. A SAS date is an integer counting days since 1 January 1960 (= 0). Dates before 1960 are negative. A SAS datetime is seconds since midnight 1 January 1960. A SAS time is seconds since midnight of the current day.
TypeUnitEpochExample value
DateDays (integer)1 Jan 1960 = 01 Jan 2024 = 23376
DatetimeSeconds (can be fractional)1 Jan 1960 00:00:00 = 01 Jan 2024 12:00 = 2,019,686,400
TimeSeconds since midnight00:00:00 = 014:30:00 = 52200

Always apply a format (e.g. DATE9., DATETIME20.) to display dates as human-readable values. Without a format, SAS displays the raw number.

Date Literals

LiteralTypeExample
'ddMONyyyy'DDate'15MAR2024'D
'ddMONyyyy:hh:mm:ss'DTDatetime'15MAR2024:14:30:00'DT
'hh:mm:ss'TTime'14:30:00'T

Current Date & Time

FunctionReturnsType
TODAY()Today's dateSAS date
DATE()Today's date (synonym)SAS date
DATETIME()Current datetimeSAS datetime
TIME()Current time of daySAS time

Extracting Date Parts

FunctionDescriptionExampleResult
YEAR(date)4-digit yearYEAR('15MAR2024'D)2024
MONTH(date)Month (1–12)MONTH('15MAR2024'D)3
DAY(date)Day of month (1–31)DAY('15MAR2024'D)15
WEEKDAY(date)Day of week (1=Sunday)WEEKDAY('15MAR2024'D)6 (Friday)
QTR(date)Quarter (1–4)QTR('15MAR2024'D)1
HOUR(time_or_dt)Hour (0–23)HOUR('14:30:00'T)14
MINUTE(time_or_dt)Minute (0–59)MINUTE('14:30:00'T)30
SECOND(time_or_dt)Second (0–59)SECOND('14:30:45'T)45
WEEK(date, opt)Week of year (opt controls start day)WEEK('15MAR2024'D, 'V')ISO week number

Date Arithmetic

Because SAS dates are integers, arithmetic is often direct:

days_between = end_date - start_date;   /* exact day difference */
tomorrow     = today() + 1;
last_week    = today() - 7;
FunctionDescriptionExampleResult
INTNX(interval, date, n)Advance by n intervals (returns start of interval)INTNX('month', '15MAR2024'D, 1)01APR2024
INTNX('month', date, 0, 'E')End of current month ('B'=begin, 'M'=middle, 'E'=end, 'S'=same)INTNX('month','15MAR2024'D, 0,'E')31MAR2024
INTNX('year', date, 0, 'B')Start of current yearINTNX('year', today(), 0, 'B')1 Jan of current year
INTCK(interval, start, end)Count intervals between datesINTCK('month','01JAN2024'D,'15MAR2024'D)2
INTCK('month', start, end, 'C')Continuous count (fractional crossing)may differ from default
INTNX vs direct arithmetic: Use INTNX when you want to stay aligned to interval boundaries (e.g. start/end of month). Use direct arithmetic for exact day counts.

Converting Between Date Types

FunctionDescriptionExample
DATEPART(datetime)Extract date from datetimeDATEPART('15MAR2024:14:30:00'DT) → SAS date
TIMEPART(datetime)Extract time from datetimeTIMEPART('15MAR2024:14:30:00'DT) → SAS time
DHMS(date, h, m, s)Build datetime from date + time partsDHMS('15MAR2024'D, 14, 30, 0) → SAS datetime
HMS(h, m, s)Build time from partsHMS(14, 30, 0)52200
MDY(m, d, y)Build date from month/day/yearMDY(3, 15, 2024) → SAS date
YYQ(y, q)First day of quarterYYQ(2024, 1) → 1 Jan 2024

Parsing Strings to Dates

ApproachDescriptionExample
INPUT(str, informat)Parse character string with date informatINPUT('2024-03-15', YYMMDD10.)
INPUT(str, DATE9.)Parse ddMONyyyy formatINPUT('15MAR2024', DATE9.)
INPUT(str, DDMMYY10.)Parse dd/mm/yyyy formatINPUT('15/03/2024', DDMMYY10.)
INPUT(str, ANYDTDTE.)Flexible informat — tries many formats automaticallyINPUT('March 15 2024', ANYDTDTE.)
INPUT(str, DATETIME.)Parse datetime stringINPUT('15MAR2024:14:30:00', DATETIME.)

Always assign the correct format after parsing: FORMAT date_var DATE9.;. Without this the variable displays as a number.

Formatting Dates as Strings

FormatExample outputExample input
DATE9.15MAR2024SAS date
DATE7.15MAR24SAS date
DDMMYY10.15/03/2024SAS date
MMDDYY10.03/15/2024SAS date
YYMMDD10.2024-03-15SAS date
WORDDATE.March 15, 2024SAS date
MONYY7.MAR2024SAS date
DATETIME20.15MAR2024:14:30:00SAS datetime
DATETIME21.215MAR2024:14:30:00.00SAS datetime
TIME8.14:30:00SAS time
/* Apply format in DATA step */
FORMAT date_var YYMMDD10.;

/* Convert to character string using PUT */
date_str = PUT(date_var, YYMMDD10.);  /* '2024-03-15' */

Common Patterns

/* First day of current month */
first_of_month = intnx('month', today(), 0, 'B');
format first_of_month date9.;

/* Last day of current month */
end_of_month = intnx('month', today(), 0, 'E');

/* First day of current year */
first_of_year = intnx('year', today(), 0, 'B');

/* Age in years */
age = intck('year', birthdate, today());
/* Adjust if birthday hasn't occurred this year yet */
if month(birthdate) > month(today()) or
   (month(birthdate) = month(today()) and day(birthdate) > day(today()))
then age = age - 1;

/* Quarter start date */
qtr_start = intnx('qtr', today(), 0, 'B');

/* Parse ISO date string from source data */
date_var = input(date_str, yymmdd10.);
format date_var date9.;

/* Check if date falls on a weekend */
if weekday(date_var) in (1, 7) then is_weekend = 1;
/* 1=Sunday, 7=Saturday */

/* Datetime to date */
date_only = datepart(dt_var);
format date_only date9.