2

I have data like:

 patid             startdate                    endday 
01S1003            9/30/2008                 3/16/2009

How do I find the number of days bewteen startdate and endday?

flag

4 Answers

4

You can use the built-in INTCK function. This function lets you get the number of time intervals (in this case 'days', but it could also be 'week','year','qtr',etc.).

data RS81;

    startdate='30sep08'd;
    endday = '16mar09'd;

    NumDays = intck( 'day', startdate, endday );

    putlog NumDays=;

    format startdate endday mmddyy10.;

run;

The signature for the function is basically:

INTCK( <interval>, <start_date>, <end_date> );

You can see all the details in the online help for INTCK or the Online SAS documentation for INTCK

link|flag
3

Days are represented in SAS as integers representing the number of days since Jan. 1, 1960 (Day Zero). So if you have your data as SAS dates, you simply subtract:

NumDays=endday - startdate;

But if those mm/dd/yyyy strings are the actual data (not just formatted representations of SAS dates), you'll need to create SAS dates, e.g.:

SAS_EndDay = input(EndDay,mmddyy10.);

To make it look like the original input (more or less):

format SAS_EndDay mmddyys10.;

There are many, many SAS informats and formats that will handle just about any representation of a date.

Also lots of handy date functions for extracting, say, the day of the week from any SAS date.

However, for finding distances such as months-between you only need the INTCK function described by Jay.

And for adjusting dates to, say, "first day of the next quarter in a fiscal year that begins in June" or "Two weeks from the following Friday", the INTNX function does the job.

Once you get the basics of SAS dates down cold, they simplify your (programming) life wonderfully.

link|flag
1

Hi. I know this question has already been answered but I thought I would present this as an alternative as the original question was a little ambiguous. For example, say you wanted to calculate a person's age (the number of full years inbetween now and the day they were born). You cannot easily use intck to do this correctly. Below I have included a macro function that I use to achieve this and similar purposes... ie. how many months has a customer been with us. Have they been with us for a full year. etc...

This macro function has been written in pure macro code so that it can be called from within a datastep or SQL function almost as easily as any in-built SAS function. I suggest putting it in your macro autocall library.

/******************************************************************************
** PROGRAM:  MACRO.INTFULL.SAS
**
** DESCRIPTION: SIMILAR TO INTCK EXCEPT THIS RETURNS THE FULL NUMBER OF 
**              PERIODS INBETWEEN THE TWO DATES YOU SPECIFY.  IE.
**
**                               INTCK   INTFULL 
** DATE1      DATE2     INTERVAL RESULT  RESULT=
** ---------  --------- -------- ------  -------
** 31-DEC-07  01-JAN-08   YEAR        1    0 
** 31-DEC-07  30-DEC-08   YEAR        1    0 (1 DAY SHORT OF A FULL YEAR)
** 31-DEC-07  31-DEC-08   YEAR        1    1 
** 20-JUL-07  18-OCT-07  MONTH        3    2 (2 DAYS SHORT OF 3 FULL MTHS)
**
** YOU CAN PASS IN ANY INTERVAL (YEAR/MONTH/DAY/ETC) THAT THE INTNX 
** FUNCTION ACCEPTS.
** 
*******************************************************************************
** VERSION:
** 1.0 ON: 05-JAN-08 BY: ROBERT PENRIDGE
**     CREATED.  
******************************************************************************/

%macro intfull(iInterval=,iStart_dt=,iEnd_dt=);
  %local first_dt second_dt cnt;

  /* 
  ** ENSURE THAT WE USE THE LOWEST DATE PROVIDED AS THE START DATE
  */
  %if &iStart_dt le &iEnd_dt %then %do;
    %let first_dt  = &iStart_dt;
    %let second_dt = &iEnd_dt;
  %end;
  %else %do;
    %let first_dt  = &iEnd_dt;
    %let second_dt = &iStart_dt;
  %end;

  %let cnt = 0;
  %let first_dt = %sysfunc(intnx(&iInterval,&first_dt,1,same));
  %do %while (&first_dt le &second_dt);
    %let cnt      = %eval(&cnt + 1);
    %let first_dt = %sysfunc(intnx(&iInterval,&first_dt,1,same));
  %end;
  &cnt
%mend;

/*
** EXAMPLE 1.  USE IN MACRO CODE
*/
%let start_dt = %sysfunc(mdy(07,1,2008));
%let end_dt   = %sysfunc(mdy(08,1,2009));
%put %intfull(iInterval=year,iStart_dt=&start_dt,iEnd_dt=&end_dt);


/*
** EXAMPLE 2.  USE WITHIN A DATASTEP USING VALUES FROM THE DATASET.
**             NOTE I HAVE 'ACCIDENTALLY' MADE THE START DATE LATER
**             THAN THE END DATE AND THE FUNCTION STILL WORKS.
*/
data xx;
  start_dt            = mdy(7,20,2008);
  end_dt              = mdy(10,18,2008);
  full_months_between = resolve(cats('%intfull(iInterval=month,iStart_dt=',start_dt,',iEnd_dt=',end_dt,')'));
  put _all_;
run;

/*
** EXAMPLE 3.  USE WITHIN AN SQL STATEMENT.
*/
proc sql noprint;
  create table zz as
  select start_dt,
         end_dt,
         resolve(cats('%intfull(iInterval=month,
                                iStart_dt=',start_dt,
                                ',iEnd_dt=',end_dt,')')) as full_months_between
  from xx;
quit;
link|flag
0

data null; sdate="12mar1998"d; edate="12jun2008"d; days=datdif(sdate,edate,'act/act'); put days; run;

Sarath

http://studysas.blogspot.com/2009/03/how-to-calculate-number-of-years-and.html

link|flag

Your Answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.