BookmarkSubscribeRSS Feed
monday89
Fluorite | Level 6

I have the following dataset. I need to subtract start and stop date in hours. If the stop date is blank, i need to make the time as midnight of that day. For example: subject 1 day 1, stop date is blank so new stop date should be: 1/1/2019 11:59 PM and then subtract two dates in hours. I am really stuck. Any help would be appreciated!

 

subjectformgroupstart datestop date
1day 11/1/19 13:55 
1day 21/2/19 14:341/2/19 19:32
1day 31/3/19 19:331/3/19 23:44
1day 41/4/19 21:49 
2day 1 2/3/19 21:332/3/19 23:44
2day 22/4/19 23:33 
2day 3 2/5/19 12:45 

 

Something like this:

subjectformgroupstart_datestop_datenew_stop_datehours
1day 11/1/19 13:55 1/1/19 23:59 
1day 21/2/19 14:341/2/19 19:321/2/19 19:32 
1day 31/3/19 19:331/3/19 23:441/3/19 23:44 
1day 41/4/19 21:49 1/4/19 23:59 
2day 1 2/3/19 21:332/3/19 23:442/3/19 23:44 
2day 22/4/19 23:33 2/4/19 23:59 
2day 3 2/5/19 12:45 2/5/19 23:59 

 

I have:

data test; set test;

if stop_ate = "" then new_stop_date = <not sure how to do end of the day midnight

else if stop_date is not null then new_stop_date = stop_date;

run;

 

data test; set test;

hours = new_stop_date-start_date;run;

 

3 REPLIES 3
PaigeMiller
Diamond | Level 26

There are a few ways to get the end of the day. I generally use the INTNX function with the 'e' option

 

if missing(stop_date) then stop_date=intnx('dtday',start_date,0,'e');

Then a subtraction gives you the length of time in seconds, and then you divide by 3600 to turn that into hours.

 

--
Paige Miller
Tom
Super User Tom
Super User

Sounds like you are using datetime values (number of seconds) and not date values (number of days).

Are your variables numeric with datetime values? Or character strings that look to humans like they mean datetime values.

To use INTNX() function to move a datetime value to the end of day you need to use the DTDAY interval (instead of the DAY interval which is for date values).  SAS will set the time part to '23:59:59't, so one second before midnight. To get a difference in datetime values in hours you just subtract them to get the number of seconds and then divide by one hour to convert to the number of hours.

data want;
  set have (rename=(start_date=start_dt stop_date=stop_dt));
  if missing(stop_dt) then stop_dt = intnx('dtday',stop_dt,0,'e');
  hours = (stop_dt - start_dt) / '01:00't ;
run;

PS I would avoid calling a datetime value a DATE.  That will cause confusion.

mkeintz
PROC Star

You've got good recommendations to use INTNX with the 'dtday' interval measure and the 'e' alignment, as in:

  stop_date=intnx('dtday',state_date,0,'e');

This will generate the 59th second of the 59th minute of 11PM.

 

But your example uses only whole minutes.  If you wish to preserve granularity by minute, just be aware that you can easily adjust the function by subtracting 59 seconds from the value generated above:

  stop_date=intnx('dtday',start_date,0,'e') - '00:00:59't;
--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 708 views
  • 0 likes
  • 4 in conversation