A long time ago I asked (and got no reply),
| I would like to express a number representing seconds of time elapsed,
| derived from incoming mail, to days, hours, minutes, and seconds: the raw
| number of seconds often has five digits and is rather hard to interpret.
|
| $SHELL is pdksh, so by forcing a shell whenever the elapsed time exceeds 59
| seconds, I can use pdksh's built-in integer arithmetic (this code is already
| in place and functioning):
[code omitted this time, but essentially, it invoked pdksh to use pdksh's
built-in integer arithmetic]
I continued,
| My guess is that despite invoking a shell, that method is more efficient in
| most cases than a recursive includerc to subtract 86400, 3600, 600, and 60
| repeatedly to get the numbers of whole days, whole hours, tens of minutes,
| and remaining minutes (leaving the number of leftover seconds). Is it?
| An untested sample of what the recursive includerc would look like is below.
[recursive includerc also omitted this time]
| Or is there some way other than repeated subtraction to code integer division
| with procmail scoring? (Multiplication is possible, but it's ugly.) Unfor-
| tunately, the reciprocals of these divisors are not terminating decimals.
| And I don't see a way to utilize the division algorithms in procmailsc's
| size tests.
Well, I finally did. It seems that procmail tends to save only the integer
portion of a score, with the weakness that any positive fraction is rounded
up to 1. [What it does with negative non-integers I haven't seen.]
Here is the final code, and it invokes no shells and uses no recursion; the
only sticking point is that it needs to make sure the quotient will be >=1
before dividing because procmail will round a positive proper fraction up
to 1, and we need all rounding to go downward. (Also, it needs a dummy one-
character variable, but we happen to have one handy.)
At any rate, I no longer need to know which of the shell invocation and the
recursion would be more efficient, as surely this is better.
________
DAYS HOURS MINUTES SECONDS_LEFT=0
:0 # only if at least one full day, or procmail will round the fraction up
* $ $ELAPSED^0
* -86399^0
{ }
:0A
* $ SECONDS_LEFT ?? $ELAPSED^1 > 86400
{
DAYS = $= # get integer of whole days
HOURS = 0 # make sure smaller variables are set in case of, say, 1d 0h 0m 3s
MINUTES = 0
:0 # subtract the seconds in the whole days
* $ $ELAPSED^0
* $ SECONDS_LEFT ?? $DAYS^1 < -86400
{ }
ELAPSED = $=
}
:0 # skip unless one full hour remains, or procmail will round fraction up
* $ $ELAPSED^0
* -3599^0
{ }
:0A
* $ SECONDS_LEFT ?? $ELAPSED^1 > 3600
{
HOURS = $= # get integer of whole hours
MINUTES = 0 # if 1 hour or more, make sure minutes are set
:0 # subtract the seconds in the whole hours
* $ $ELAPSED^0
* $ SECONDS_LEFT ?? $HOURS^1 < -3600
{ }
ELAPSED = $=
}
:0 # only if at least one full minute is left, or procmail will round up
* $ $ELAPSED^0
* -59^0
{ }
:0A
* $ SECONDS_LEFT ?? $ELAPSED^1 > 60
{
MINUTES = $= # get integer of whole minutes
:0 # subtract the seconds in the whole minutes
* $ $ELAPSED^0
* $ SECONDS_LEFT ?? $MINUTES^1 < -60
{ }
ELAPSED = $=
}
SECONDS_LEFT=$ELAPSED # save leftover seconds and create string
LAPSE = "${DAYS+${DAYS}d }${HOURS+${HOURS}h }${MINUTES+${MINUTES}m
}${SECONDS_LEFT}s"