SAS numeric formats round the values they display.
For example, if you use the
F5. format to display
the value 1.54, it displays as 2, because the value is closer to
2 than it is to 1. SAS also rounds clock values, and this can lead to
results you might not expect, because it is different from the
conventional treatment of clock values.
For example, if the time of day is 7:44:45, this is conventionally reported in hours and minutes as 7:44, not 7:45. Usually, people expect the written time 7:44 to encompass the minute from 7:44:00.000 to 7:44:59.999, as it does when they see it on a digital clock. But SAS might display this time of day as 7:44 or 7:45, depending on what format you select. It is important to select the correct format according to the kind of rounding you want to display. If you are viewing a SAS display of clock values, you can avoid confusion if you remember that the times displayed can be an increment later than the actual values.
A format that displays clock values rounds according to the smallest
unit that format can display. The TIME and DATETIME formats can display
seconds, so they round the values they display to the nearest second.
But the HHMM format displays hours and minutes, so it rounds values
to the nearest minute. This means that the
HHMM5. formats often display values differently, as
this example demonstrates.
VALUE = '7:44:45'T;
PUT 'TIME' @9 VALUE TIME5.
/ 'HHMM' @9 VALUE HHMM5.;
TIME 7:44 HHMM 7:45
The TIME format rounds to the nearest second and displays the time as 7:44, but the HHMM format rounds to the nearest minute and displays 7:45.
The HOUR format goes farther, rounding values to the nearest hour. It
displays the time of 7:44:45 as 8. This rounding makes the HOUR format a poor
choice for displaying time of day values related to a schedule or any organized activity.
TIME2. format would be a better choice.
With a decimal argument, a format rounds to the decimal places it displays.
For example, the
TIME12.3 format displays seconds with three
decimal places and rounds to the nearest .001 second. Thus, you can reduce
the rounding of a format just by displaying more decimal places.
Rounding becomes most evident for values that are near midnight. Formats that use a 24-hour clock display near-midnight values as 24:00:00; this could become a problem if you assume that the 24-hour clock ends with hour 23. Formats that use a 12-hour clock display near-midnight values, those that are close enough to be rounded to midnight, as 12 a.m. of the next day. This means that the DATETIME and DATEAMPM formats may display the same near-midnight value as belonging to different days, as you can see in this demonstration.
VALUE = '31DEC1999 23:59:59.9'DT;
PUT 'DATETIME' @13 VALUE DATETIME19. @48 VALUE DATETIME9.
/ 'DATEAMPM' @13 VALUE DATEAMPM22. @48 VALUE DATEAMPM9.;
DATETIME 31DEC1999:24:00:00 31DEC1999 DATEAMPM 01JAN2000:12:00:00 AM 01JAN2000
SAS date formats do not round values, but they do fuzz them,
rounding if a value is within
1E-12 of an integer.
If you have time of day information in a SAS date value, a format
starts the new day 86.4 nanoseconds before midnight —
not a significant discrepancy for most applications.
Of course, most SAS date values are integer values to begin with,
indicating only a date, so truncation, rounding, and fuzzing are not an issue.
You can completely avoid rounding of clock values by using
picture formats in place of the built-in SAS datetime and time formats.
Many programmers aren’t aware that they can create picture formats
for time values, but this feature of the PICTURE statement was
introduced in version 7, and the definition of a picture format can
be quite simple. As an example, these statements define the picture
format TIME8T, which is the equivalent of the
format, but with truncation instead of rounding:
PICTURE TIME8T OTHER='%H:%0M:%0S' (DATATYPE=DATETIME);
Using the picture option DATATYPE=DATETIME allows the picture format to accept either a SAS datetime value or a SAS time value. The following step’s output demonstrates that the picture format truncates where the SAS format rounds.
VALUE = '23:59:59.9'T;
PUT 'TIME' @11 VALUE TIME8.
/ 'TIME8T' @11 VALUE TIME8T8.;
TIME 24:00:00 TIME8T 23:59:59
The syntax of the PICTURE statement includes a ROUND picture option to allow rounding in pictures for numbers, but this option does not work with time values. Picture formats for time ignore the ROUND option. They always truncate.
Another way to be sure clock values are displayed correctly is by using the FLOOR function to create a truncated value. If a variable contains a value that is already truncated, then the format does not need to round or truncate. This statement removes the fractional seconds from the variable VALUE so that it contains only whole seconds:
VALUE = FLOOR(VALUE);
The INTNX function also truncates values if you use it with an increment argument of 0.
SAS formats round, and the way they round time values departs from the conventional way of writing time values. However, this rounding won’t confuse or mislead you if you are aware of it when you read formatted time values, and you can avoid rounding, when necessary, by using truncation functions or picture formats.