Hi there. I can find plenty of stuff on displaying date/time values but not much on displaying time interval values. All the formats seem to be about points in time.
I have a numeric field holding a time interval in seconds .e.g. 3600. This is a time interval and not a point in time 3600 seconds after 1 Jan 1960 so the usual time formats don't seem to apply.
I want to display this as xx hours yy mins zz secs
e.g. 3600 seconds will display as 1 hours 0 mins 0 secs
e.g. 360000 seconds will display as 100 hours 0 mins 0 secs
e.g. 360065 seconds will display as 100 hours 1 mins 5 secs
I don't see how to do this with picture etc in a format. Ok it looks possible to convert seconds to just hours or just minutes but to display like this....
I imagine this is a common enough requirement so is there a format out there I am missing. Or any ideas for creating one?
The first 'solution' I can think of is this hack (not pretty)
test = cat(scan(put(seconds,hhmm6.0),1,':'),' hours ',m,' mins ',s,' secs');
And I can't think of how to do it with a picture format. The Hour directive will only display 0-23.
low-high = '%H hours %M mins %S secs' (datatype=time);
put seconds intervalX.;
Finally the following example - Generate a dataset with your range of values and use this as an input for your format.
do i= 1 to 360065;
start = i;
label= cat(scan(put(i,hhmm6.0),1,':'),' hours ',minute(i),' mins ',second(i),' secs');
proc format cntlin=interval;
put seconds interval.;
And your right - Strange that SAS does not have a format for this - perhaps in 9.21 :-)
1 & 3 are great solutions. 3. is perfect because I can re-use that format wherever I need. One small change: I had to replace "put seconds interval.;" with
"format seconds interval.;" to pick up the new format.
just use the time format.
Here is an example (tested in SAS9.1.3 on zOS)[pre]
34 %let fromdt= 12Oct2008:0:0:0 ;
35 %let TOdt= 23Oct2008:14:15:20.123 ;
36 %put duration = %sysfunc( range( "&fromDT"dt, "&toDT"dt ), time14 );
duration = 278:15:20 [/pre]
The RANGE() function has calculated the difference between two datetime values, and %SYSFUNC() formatted the result using the TIME. format
Internally, datetime values are a (real) number of seconds since the beginning of 1Jan1960, so the difference is a (real) number of seconds.
does this not show that the TIME format provides the duration format required?
Ah! That works pretty well. The only thing is that the output looks obscure to some of my users so explicitly showing hours, mins, seconds means they know the precise meaning of the field. All the existing formats like that seem to revert to the 24 hour clock so won't hold values over 24 hours. (I could definitely be wrong though. Could be a format out there.)
Combining the RANGE/TIME14 approach with a bit of character function magic might give you what you want...since TIME14 will result in 0 hours, etc. (I didn't use macro variables in the data step because I wanted to show 2 obs with diff values for duration and it seems you'll probably be doing this in a data step program because there really isn't a format that will do exactly what you want. You'll have to construct your own character string.)
Thanks Cynthia. I do want to keep the field numeric though so the users can manipulate it and the re-use of a format is handy so went with the solution to create the format through cntlin. But this is brilliant. Learned more from this thread than I did in weeks programming by myself.
Yeah, I finally realised that my assumption about the time format was wrong after looking at the last post! But still had to generate own format as per instructions above to get the one I wanted that showed the units of measurement more clearly and was still numeric.