It’s Later Than It Is

Rounding of Clock Values in SAS Formats

Rick Aster

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.

Rounding Rules

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 TIME5. and HHMM5. formats often display values differently, as this example demonstrates.

DATA _NULL_;
VALUE = '7:44:45'T;
PUT 'TIME' @9 VALUE TIME5.
/ 'HHMM' @9 VALUE HHMM5.;
RUN;
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. The 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.

Almost Midnight

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.

DATA _NULL_;
VALUE = '31DEC1999 23:59:59.9'DT;
PUT 'DATETIME' @13 VALUE DATETIME19. @48 VALUE DATETIME9.
/ 'DATEAMPM' @13 VALUE DATEAMPM22. @48 VALUE DATEAMPM9.;
RUN;
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.

Picture Formats

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 TIME8. format, but with truncation instead of rounding:

PROC FORMAT;
PICTURE TIME8T OTHER='%H:%0M:%0S' (DATATYPE=DATETIME);
RUN;

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.

DATA _NULL_;
VALUE = '23:59:59.9'T;
PUT 'TIME' @11 VALUE TIME8.
/ 'TIME8T' @11 VALUE TIME8T8.;
RUN;
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.

Assigning Truncated Values

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.

Accurate Time

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.

 O /\

Global
Statements

RICK ASTER

SAS

BOOKS

Tech | Dictionary

Download | Rastinate

Techniques

Projects

Also see:

Dictionary

Start Here

Q & A

Rick Aster