When rounding up the fractional portion of the printed value, increment
the seconds portion if necessary (instead of printing ':', i.e. '0'+10).
TIMEFORMAT='%0R %1R %2R %6R'
for _ in {1..5}; { time sleep 0.98; }
0 0.: 0.98 0.984048
0 0.: 0.99 0.992579
0 0.: 0.:0 0.999416
0 0.: 0.:0 0.998138
1 1.0 1.00 1.001916
Also, I'm assuming it was not intentional that values with a precision
of 0 were being truncated while all other precisions were rounded (but
maybe it was?).
---
execute_cmd.c | 56 ++++++++++++++++++++++++++++-----------------------
1 file changed, 31 insertions(+), 25 deletions(-)
diff --git a/execute_cmd.c b/execute_cmd.c
index 436f37ba..92b9f1fc 100644
--- a/execute_cmd.c
+++ b/execute_cmd.c
@@ -1278,13 +1278,43 @@ static const int maxvals[] = { 1, 10, 100, 1000, 10000,
100000, 10000000 };
/* Expand one `%'-prefixed escape sequence from a time format string. */
/* SEC_FRACTION is in usecs. We normalize and round that based on the
precision. */
-int
+static int
mkfmt (char *buf, int prec, int lng, time_t sec, long sec_fraction)
{
time_t min;
char abuf[INT_STRLEN_BOUND(time_t) + 1];
int ind, aind;
+ /* We want to add a decimal point and PREC places after it if PREC is
+ nonzero. PREC is not greater than 6. SEC_FRACTION is between 0
+ and 999999 (microseconds). */
+ if (0 <= prec && prec < 6)
+ {
+ /* We round here because we changed timeval_to_secs to return
+ microseconds and normalized clock_t_to_secs's fractional return
+ value to microseconds, deferring the work to be done to now.
+
+ Cut off digits in excess of PREC from SEC_FRACTION, round up if
+ necessary, handle potential overflow into SEC, then convert back
+ to microseconds. */
+ int frac, rest, maxval;
+
+ maxval = maxvals[6 - prec];
+ frac = sec_fraction / maxval;
+ rest = sec_fraction % maxval;
+
+ if (rest >= maxval/2)
+ frac++;
+
+ if (frac == maxvals[prec])
+ {
+ sec++;
+ sec_fraction = 0;
+ }
+ else
+ sec_fraction = frac * (1000000 / maxvals[prec]);
+ }
+
ind = 0;
abuf[sizeof(abuf) - 1] = '\0';
@@ -1312,32 +1342,8 @@ mkfmt (char *buf, int prec, int lng, time_t sec, long
sec_fraction)
while (abuf[aind])
buf[ind++] = abuf[aind++];
- /* We want to add a decimal point and PREC places after it if PREC is
- nonzero. PREC is not greater than 6. SEC_FRACTION is between 0
- and 999999 (microseconds). */
if (prec != 0)
{
- /* We round here because we changed timeval_to_secs to return
- microseconds and normalized clock_t_to_secs's fractional return
- value to microseconds, deferring the work to be done to now.
-
- sec_fraction is in microseconds. Take the value, cut off what we
- don't want, round up if necessary, then convert back to
- microseconds. */
- if (prec != 6)
- {
- int frac, rest, maxval;
-
- maxval = maxvals[6 - prec];
- frac = sec_fraction / maxval;
- rest = sec_fraction % maxval;
-
- if (rest >= maxval/2)
- frac++;
-
- sec_fraction = frac * (1000000 / maxvals[prec]);
- }
-
buf[ind++] = locale_decpoint ();
for (aind = 1; aind <= prec; aind++)
{
--
2.51.0