SAS Data Integration Studio, DataFlux Data Management Studio, SAS/ACCESS, SAS Data Loader for Hadoop and others

call is8601_convert

Accepted Solution Solved
Reply
Contributor
Posts: 26
Accepted Solution

call is8601_convert

I’m trying to create a variable corresponding to the duration in days between two datetime variables START and END which are in $N8601E. format displayed as yyyy-mm-ddThh:mm in my original dataset.

 

I have tried the Call is8601_Convert routine but my server crashes every time I run the code below.

 

data want;

set have;

       length DURATION $16;

       call is8601_convert('dt/dt','du', START, END, DURATION);

       format DURATION $n8601e.;

run;

 

If I omit the line length TRTDURD $16; the variable DURATION corresponds to values that I can’t make sense of as shown below.

 

START                               END                                   DURATION

2011-11-21T11:15             2012-02-08T08:15             32562000

2012-04-13T11:00             2012-07-05T10:00             7081200

2012-04-16T09:40             2012-07-04T05:40             6724800

 

Any ideas on how to fix this to get the Duration variables displaying a Number of days (and another variable displaying the PnYnMnD format) would be greatly appreciated.


Accepted Solutions
Solution
‎10-26-2016 10:34 AM
Contributor
Posts: 26

Re: call is8601_convert

[ Edited ]
Posted in reply to data_null__

I had no success with both approaches. I believe my problem lies in the format of the START and END variables which Proc Content indicates are in $N8601E. format. When I run the following code, I get errors stating Variables "START" (and "END") has already been defined as a numeric. I tried changing the format of START and END but I always get the same error. If I try changing the format of the START and END to YYMMDD. or any Numeric format, the values just disappear. Nevertheless, this code works if I use date variables with original format YYMMDD. in place of START and END.  

 

data want;

length DURATION $16;

call is8601_convert('dt/dt','du',START,END,DURATION);

format DURATION $N8601E.;

set have;

run;

 

Anyways, after trying different things, I found that the following code works perfectly with START and END in $N8601E. format even though I thought that using the INPUT function, the format indicated should be the format of the original variable, not the new variable... anyway, this works... 

 

data want;

set have;

STARTN=input(START, IS8601DA.);

ENDN=input(END, IS8601DA.);

DURATION=DATDIF(STARTN,ENDN,'actual');

run;

 

output:

START                               END                                   DURATION

2011-11-21T11:15             2012-02-08T08:15             79

2011-12-14T11:35             2012-03-05T09:45             82

2012-04-13T11:00             2012-07-05T10:00             83

2012-04-16T09:40             2012-07-04T05:40             79

 

View solution in original post


All Replies
Super User
Posts: 11,343

Re: call is8601_convert

Are you attempting this in another database?

 

Your format information, if correct tells me that your variables are currently SAS datetime values. To find intervals between them use the INTCK function:

 

Duration = intck('hour',start, end);

 

You may need to provide a format for the result if you want to something other than the number of seconds.

 

Note that with datetimes to get DATE based intervals such as days, weeks, months that you specify an interval ending in DT such as

Duration = intck('daydt',start, end);

 

Respected Advisor
Posts: 3,799

Re: call is8601_convert

When DURATION is numeric the value returned is number of seconds in the duration.  However I don't understand why it does't work for you when DURATION is character as that does work for me.

 

data want;
   input (start end)(:e8601dt.);
   length DURATION $16;
   call is8601_convert('dt/dt','du', START, END, DURATION);
   call is8601_convert('dt/dt','du', START, END, DURATION2);
   format DURATION $n8601e.;
   format start end e8601dt.;
   format duration2 datetime20.;
   cards;
2011-11-21T11:15:00 2012-02-08T08:15:00
2012-04-13T11:00:00 2012-07-05T10:00:00
2012-04-16T09:40:00 2012-07-04T05:40:00
;;;;
   run;
proc print;
   run;

Capture.PNG

Solution
‎10-26-2016 10:34 AM
Contributor
Posts: 26

Re: call is8601_convert

[ Edited ]
Posted in reply to data_null__

I had no success with both approaches. I believe my problem lies in the format of the START and END variables which Proc Content indicates are in $N8601E. format. When I run the following code, I get errors stating Variables "START" (and "END") has already been defined as a numeric. I tried changing the format of START and END but I always get the same error. If I try changing the format of the START and END to YYMMDD. or any Numeric format, the values just disappear. Nevertheless, this code works if I use date variables with original format YYMMDD. in place of START and END.  

 

data want;

length DURATION $16;

call is8601_convert('dt/dt','du',START,END,DURATION);

format DURATION $N8601E.;

set have;

run;

 

Anyways, after trying different things, I found that the following code works perfectly with START and END in $N8601E. format even though I thought that using the INPUT function, the format indicated should be the format of the original variable, not the new variable... anyway, this works... 

 

data want;

set have;

STARTN=input(START, IS8601DA.);

ENDN=input(END, IS8601DA.);

DURATION=DATDIF(STARTN,ENDN,'actual');

run;

 

output:

START                               END                                   DURATION

2011-11-21T11:15             2012-02-08T08:15             79

2011-12-14T11:35             2012-03-05T09:45             82

2012-04-13T11:00             2012-07-05T10:00             83

2012-04-16T09:40             2012-07-04T05:40             79

 

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 3 replies
  • 362 views
  • 0 likes
  • 3 in conversation