BookmarkSubscribeRSS Feed
Jeff_DOC
Pyrite | Level 9

Good morning. Any help would be greatly appreciated. I am using the SAS examples from other questions but can't seem to get either to work. It may not be the best approach so I'm open to any help. 

 

I have a standard start date and a numeric time (in two separate fields) and a standard end date and numeric time (in two separate fields). I need to find the number of hours between the two-it could be a start date with a return date a day or two later-it may not always be the same date.

 

On attempt one I only get missing results, on attempt two I get a conversion like 1405 = 14:05

 

I have a feeling there's a simple solution, but I can't seem to work it out.

 

Thank you very much.

 

Attempt one:
	trip_time_standard = hms(input(substr(trip_time, 1, 2), best.), input(substr(trip_time, 3, 2), best.), 0);

I get all missing results.

Attempt two:

data court_19;
	set court_18;
	trip_time_test = trip_time;
	trip_return_time_test = trip_return_time;
		t = input(trip_time, best.);
		trip_time_DT = hms(int(t/100), mod(t,100), 0);
		t = input(trip_return_time, best.);
		trip_return_time_DT = hms(int(t/100), mod(t,100), 0);
		format trip_time_DT trip_return_time_DT hhmm5.;
run;




reference_date idnum trip_date TRIP_TIME trip_return_date TRIP_RETURN_TIME trip_time_test trip_return_time_test t trip_time_DT trip_return_time_DT
1/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
2/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
3/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
4/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
5/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
6/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
7/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
8/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
9/1/2018 636 7/11/2009 1416 7/11/2009 1950 1416 1950 1950 14:16 19:50
9 REPLIES 9
PaigeMiller
Diamond | Level 26

"I have a standard start date and a numeric time (in two separate fields)" — what are the variable names? Please don't make us assume we know which variables you are referring to, because we could get it wrong. Better, you should specifically tell us. Also, are these variables numeric or character according to PROC CONTENTS?

 

"... and a standard end date and numeric time (in two separate fields)" again we need the same information as above.

 

Your data doesn't vary except in the leftmost column REFERENCE_DATE. Maybe a more realistic example would be helpful. And also, we need data provided in a form we can use, which is WORKING SAS data step code (examples and instructions).

--
Paige Miller
Jeff_DOC
Pyrite | Level 9

Hi. You are correct in the non-variability of the data. I only used the first few rows so as to not overwhelm the issue. My assumption is that if it worked for one record I could make it work for others. 

Tom
Super User Tom
Super User

To create a DATETIME value from a DATE and TIME value you can use the DHMS() function.  Just put the TIME into the SECONDS field and set the HOURS and MINUTES to zero.

datetime =dhms(date,0,0,time);
format datetime datetime19.;

 

What type of values do your DATE variables have? The look like they might be strings with values in either MDY or DMY style.  We cannot tell which from the example printout you shared.  To convert such strings into dates use the INPUT function with the appropriate informat for the style they are using.

input(date,mmddyy10.)

Note the printout does not look like it has SAS date variables since those would normally print one digit month or day values with the leading zeros.  01/01/2018 instead of 1/1/2018.

 

What type of values do your TIME variables have?  They LOOK like 1416 and 1950 in your printout, but are they character or numeric? If numeric what display format is being used (if any)?  They might just be the integers 1,416 and 1,950 printed with the default BEST format.  Or they might be actual TIME values printed with the HHMM4. format.

 

If the they are numeric you don't want to use INPUT() to try to convert them to another number.  The INPUT() function converts strings into values.  So it you pass it a number instead of a string SAS will first convert the number into a string using the BEST12. format which will result in a lot of leading spaces for such small numbers.

 

Similarly the SUBSTR() function wants a string for the first argument.  So trying to use something like SUBSTR(time,3,2) on a numeric variable with values like 1,950 or 1,416 will return two blanks because of all of those leading spaces the conversion created.

 

If the TIME variables are character you could append '00' for the seconds and then use the HHMMSS6. informat to create a time value.

input(cats(time,'00',hhmmss6.)

And if the TIME variables are numeric, but not actual time values, you can use arithmetic to create a time value.  So assuming the digits represent H,HMM then you could use:

60*(60*int(time/100) + mod(time,100))

Once you have two DATETIME values make sure to attach a DATETIME format (not a TIME format).  

 

You can subtract two DATETIME values and the difference is in seconds.  You could display the seconds using the TIME format to see how many hours, minutes and seconds they contain.  If the number of hours is larger then 24 then the TIME format will display that (as long as you make the width long enough).

328  data test;
329   diff = '02MAY2025:19:50'dt - '01MAY2025:14:16'dt ;
330   put diff time12.;
331  run;

    29:34:00

 

 

 

Jeff_DOC
Pyrite | Level 9

You are correct in that my dates have a specific format, I didn't think that would matter since SAS seems to understand it's a date regardless.

 

Also, the time, both trip_time and trip_return_time, are both numeric. I now see why the substr function didn't work. Thanks for that. The time variables have no specific formatting-they are simply numeric. 

Using a trip_date of 7/11/2009 and a trip time of 1416 here's what I get - 

 

Your initial suggestion: 

datetime =dhms(date,0,0,time);
format datetime datetime19.;

 Seems to get most of the way there so I'm assuming I've not addressed something in there. The result I get using the below:

	datetime =dhms(trip_date,0,0, trip_time);
	format datetime datetime19.;

is: 11JUL2009:00:23:36

 

I believe what I should be getting is 11JUL2009:14:16:00 so I can use subtraction to determine the difference between the trip information and the trip return information.

 

I obviously do not understand working with time values as well as I need to.

 

 

 

 

Tom
Super User Tom
Super User

TIME values are counts of seconds.  The value of 1,416 seconds represents 23 minutes and 36 seconds.

350  data test;
351    time=1416;
352    put time tod8.;
353  run;

00:23:36

14 hours and 16 minutes is 51,360 seconds.

354  data test;
355    time='14:16:00't ;
356    put time :comma12.;
357  run;

51,360

To convert your values like 1,416 into actual TIME values take the number of HOURS, int(time,100) and the number of MINUTES, mod(time,100), and convert them into seconds.  Here are a couple of ways to do that.

60*(60*int(time/100)+mod(time,100))
input(put(time*100,Z6.),hhmmss6.)

Example:

372  data test;
373    time=1416;
374    time1=60*(60*int(time/100)+mod(time,100));
375    time2=input(put(time*100,Z6.),hhmmss6.);
376    put (time:) (=comma12.);
377    put (time:) (=time12.);
378  run;

time=1,416 time1=51,360 time2=51,360
time=0:23:36 time1=14:16:00 time2=14:16:00

You could also do it in your DHMS() function call.

datetime =dhms(trip_date,int(trip_time/100),mod(trip_time,100),0)

 

 

dxiao2017
Pyrite | Level 9

Hi @Jeff_DOC , base on your question and @Tom 's instruction, my solution is as follows. Please kindly let me if it answer your question @Jeff_DOC , many thanks!

data timeraw1;
   input refdate mmddyy10. idnum 
         tripd mmddyy10. tript
         returnd mmddyy10. returnt;
   format refdate tripd returnd mmddyy10.
          tript returnt time.;
   datalines;
01/01/2018 636 7/11/2009 1416 7/11/2009 1950
02/01/2018 636 7/11/2009 1416 7/12/2009 1950
;
run;
proc print data=timeraw1;run;
data timediff;
   set timeraw1;
   tripdt=dhms(tripd,0,0,tript);
   returndt=dhms(returnd,0,0,returnt);
   diff=returndt-tripdt;
   format tripdt returndt datetime19.
          diff time12.;
run;
proc print data=timediff;run;

dxiao2017_0-1748614876745.png

dxiao2017_1-1748614939252.png

SAS help cars; we are cars; that is why my default image;
Tom
Super User Tom
Super User

You are you reading the string 1416 as a plain old number and then treating it as a time value. 

1416 seconds is 23 minutes and 36 seconds, as your output shows.

 

Is that what you intended?

dxiao2017
Pyrite | Level 9

Hi @Tom ,thanks a lot for your question! Here is the further clarification: according to @Jeff_DOC 's description about the time variable, the values such as 1416 and 1950 may have two different meanings:

 

1) they are standard time values in numeric format (i.e., numbers that we see and use everyday), in this case, any of this kind of numbers can be converted to a standard time format such as 00:00 through apply the time. format to them; and just like what you already clearly described in your previous thread, @Tom , these numbers represent seconds (I did not pay attention to this knowledge before, because I just know that any number in a date/time column can be easily converted to standard date/time format and I did not worry about what they are exactly);

 

2) 1416 and 1950 means 14:16pm and 19:50pm, in this case, one can convert the number to a character format using cat(substr(put() )) function, and then convert the character time back to numeric time value and use it in calculating time difference.

 

Also, I think @Tom , your previous thread already well answered and clearly explained your question, and my solution is in accordance with yours (see the screen capture), thanks a lot for your questions, which makes me learnt more!

Untitled1.png

 My answer:

Untitled2.png

Untitled3.png

SAS help cars; we are cars; that is why my default image;
dxiao2017
Pyrite | Level 9

And @Jeff_DOC , base on your question and @Tom 's instruction, if your time variable value 1416  and 1950 do represent 14:16 and 19:50, the solution is as follows. Please kindly let me know if it answer your question, @Jeff_DOC ,many thanks!

data timeraw2;
   input refdate mmddyy10. idnum 
         tripd mmddyy10. tript
         returnd mmddyy10. returnt;
   format refdate tripd returnd mmddyy10.;
   datalines;
01/01/2018 636 7/11/2009 1416 7/11/2009 1950
02/01/2018 636 7/11/2009 1416 7/12/2009 1950
;
run;
proc print data=timeraw2;run;
data timeraw2a;
   set timeraw2;
   tript1=cat(substr(put(tript,4.),1,2),
               ':',
               substr(put(tript,4.),3,2)
              );
   returnt1=cat(substr(put(returnt,4.),1,2),
                 ':',
                 substr(put(returnt,4.),3,2)
                );
   triptnum=input(tript1,time.);
   returntnum=input(returnt1,time.);
run;
proc print data=timeraw2a;run;
data timediff2;
   set timeraw2a;
   tripdt=dhms(tripd,0,0,triptnum);
   returndt=dhms(returnd,0,0,returntnum);
   diff=returndt-tripdt;
   format tripdt returndt datetime19.
          diff time12.;
run;
proc print data=timediff2;run;

dxiao2017_0-1748617049759.png

 

SAS help cars; we are cars; that is why my default image;

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 9 replies
  • 994 views
  • 4 likes
  • 4 in conversation